2013-06-28 4 views
2

15 년간의 강수량 데이터가있는 10 개의 스테이션이 있습니다. 모두는 무작위로 그들의 시리즈에서 몇 시간, 심지어 날 뛰기를 가지고있다. 나는 각 스테이션의 점프에 NA (또는 일부 이웃들의 평균)를 제공하면서 15 년간의 모든 시간 간격을 인덱스로 사용하고 모든 스테이션 데이터를 하나의 데이터 프레임에 결합하고자합니다. 그래서 어떤 제안이 R에서? 예를 들어시간별 강우량 데이터를 병합하는 방법

나는 데이터 프레임 rainfall_1

date      station210 
1994-01-01 00:00:00 0 
1994-01-01 02:00:00 0 
1994-01-01 03:00:00 0 
1994-01-01 04:00:00 0.6 
1994-01-01 06:00:00 2.6 
1994-01-01 07:00:00 3.2 

이 두 번째 역은 내가

merge(rainfall_1, rainfall_2, all=TRUE) 
date    station_210 station_212 
1994-01-01 00:00:00 0.0 0.0 
1994-01-01 02:00:00 0.0 1.8 
1994-01-01 03:00:00 0.0 1.8 
1994-01-01 04:00:00 0.6 1.4 
1994-01-01 06:00:00 2.6 1.8 

하려고 할 때 몇 가지 문제는 그것이 미스를하지

date      station212 
1994-01-01 00:00:00 0 
1994-01-01 01:00:00 1.8 
1994-01-01 02:00:00 1.8 
1994-01-01 03:00:00 1.8 
1994-01-01 04:00:00 1.4 
1994-01-01 06:00:00 1.8 

rainfall_2 있습니다입니다 두 번째 데이터 프레임의 두 번째 행 (rainfall_2)은 5 번째 시간에 값이 누락됩니다. 두 데이터 프레임 모두에 존재하지 않습니다. 나는 두 번째 시간 단계 (2 시간)가 포함되고 이웃의 NA 또는 평균이되고 다섯 번째 시간 단계가 NA 또는 이웃의 평균값을 제공하는 솔루션을 찾고있었습니다.

이러한 시계열 데이터가 임의의 간격으로 누락 된 많은 스테이션의 수천에 대한 데이터 인 경우를 상상해보십시오.

+2

재현 할 수있는 예제 (예 : 코드 및 예제 데이터)를 제공하여 도와 드리겠습니다. http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible 자세한 내용은 예제를 참조하십시오. –

+0

필요성을 강조하기 위해 R의 시간 처리 함수는 ... 다르게 가정 해 봅시다. 정말로, 실제로 데이터를 볼 필요가 있습니다. 경험에 따르면 SO의 신규 사용자는 정중 요청 이후 이러한 데이터를 제공하지 않으므로 가까운 투표를해야합니다. 그러나 폐쇄를 막기 위해 질문하고 편집 해 주시기 바랍니다. –

+0

'dput (rainfall_1)'과'dput (rainfall_2) '의 결과를 보여 주면 응답자가 더 쉬울 것입니다. –

답변

0

나는 이것이 당신이 원하는 것을 할 것이라고 생각합니다. 1 월 1 일 자정 대신 12 월 31 일 오후 3시에 마지막 병합 데이터 집합이 왜 시작되는지 잘 모르겠습니다. GMT와 관련된 컴퓨터의 시계와 관련이 있다고 생각합니다.

df.1 <- read.table(text = ' 
date  time  station210 
1994-01-01 00:00:00 0 
1994-01-01 02:00:00 0 
1994-01-01 03:00:00 0 
1994-01-01 04:00:00 0.6 
1994-01-01 06:00:00 2.6 
1994-01-01 07:00:00 3.2 
', header = TRUE, stringsAsFactors=FALSE) 

df.2 <- read.table(text = ' 
date  time station212 
1994-01-01 00:00:00 0 
1994-01-01 01:00:00 1.8 
1994-01-01 02:00:00 1.8 
1994-01-01 03:00:00 1.8 
1994-01-01 04:00:00 1.4 
1994-01-01 06:00:00 1.8 
', header=TRUE, stringsAsFactors=FALSE) 

cols <- c('date' , 'time') 

df.1$datetime <- apply(df.1[ , cols ] , 1 , paste , collapse = " ") 
df.2$datetime <- apply(df.2[ , cols ] , 1 , paste , collapse = " ") 

df.1 <- df.1[, c('datetime', 'station210')] 
df.2 <- df.2[, c('datetime', 'station212')] 

df.3 <- merge(df.1, df.2, by="datetime", all=TRUE) 

df.3[order(df.3$datetime),] 

df.3$datetime <- format(as.POSIXct(df.3$datetime, format = "%Y-%m-%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S") 
df.3 

hour <- seq(0,60*60*24,by=60*60) 

datetime <- as.POSIXlt(hour, origin="1994-01-01") 

datetime <- format(as.POSIXct(hour, origin="1994-01-01"), "%Y-%m-%d %H:%M:%S" ) 

newdf <- merge(data.frame(datetime), df.3, all.x=TRUE, by="datetime") 
newdf 

       datetime station210 station212 
1 1993-12-31 15:00:00   NA   NA 
2 1993-12-31 16:00:00   NA   NA 
3 1993-12-31 17:00:00   NA   NA 
4 1993-12-31 18:00:00   NA   NA 
5 1993-12-31 19:00:00   NA   NA 
6 1993-12-31 20:00:00   NA   NA 
7 1993-12-31 21:00:00   NA   NA 
8 1993-12-31 22:00:00   NA   NA 
9 1993-12-31 23:00:00   NA   NA 
10 1994-01-01 00:00:00  0.0  0.0 
11 1994-01-01 01:00:00   NA  1.8 
12 1994-01-01 02:00:00  0.0  1.8 
13 1994-01-01 03:00:00  0.0  1.8 
14 1994-01-01 04:00:00  0.6  1.4 
15 1994-01-01 05:00:00   NA   NA 
16 1994-01-01 06:00:00  2.6  1.8 
17 1994-01-01 07:00:00  3.2   NA 
18 1994-01-01 08:00:00   NA   NA 
19 1994-01-01 09:00:00   NA   NA 
20 1994-01-01 10:00:00   NA   NA 
21 1994-01-01 11:00:00   NA   NA 
22 1994-01-01 12:00:00   NA   NA 
23 1994-01-01 13:00:00   NA   NA 
24 1994-01-01 14:00:00   NA   NA 
25 1994-01-01 15:00:00   NA   NA 

편집 - 2013년 7월 6일

여기에 두 개 이상의 데이터 프레임을 처리 할 수있는 한 가지 방법입니다.

df.1 <- read.table(text = ' 
date  time  station210 
1994-01-01 00:00:00 0 
1994-01-01 02:00:00 0 
1994-01-01 03:00:00 0 
1994-01-01 04:00:00 0.6 
1994-01-01 06:00:00 2.6 
1994-01-01 07:00:00 3.2 
', header = TRUE, stringsAsFactors=FALSE) 

df.2 <- read.table(text = ' 
date  time station212 
1994-01-01 00:00:00 0 
1994-01-01 01:00:00 1.8 
1994-01-01 02:00:00 1.8 
1994-01-01 03:00:00 1.8 
1994-01-01 04:00:00 1.4 
1994-01-01 06:00:00 1.8 
', header=TRUE, stringsAsFactors=FALSE) 

df.3 <- read.table(text = ' 
date  time station214 
1993-12-31 22:00:00 5.0 
1993-12-31 23:00:00 2.0 
1994-01-01 02:00:00 1.0 
1994-01-01 04:00:00 3.0 
1994-01-01 06:00:00 5.0 
1994-01-01 08:00:00 4.0 
', header=TRUE, stringsAsFactors=FALSE) 

는 데이터 프레임의 목록을 작성하고 변수 datetime 만들 :

my.data <- sapply(paste('df.', seq(1,3,1), sep=''), get, environment(), simplify = FALSE) 

date.time <- function(x) { 
         cols <- c('date' , 'time') 
         x$datetime <- apply(x[ , cols ] , 1 , paste , collapse = " ") 
         x <- x[, 3:4] 
         return(x) 
      } 

my.list <- lapply(my.data, function(x) date.time(x)) 

병합을하고 그 목록의 데이터 프레임을 분류 :

df.3 <- Reduce(function(...) merge(..., all=T), my.list) 
df.3[order(df.3$datetime),] 
다음

데이터입니다

병합 된 데이터 프레임에 누락 된 날짜와 시간을 추가합니다.

df.3$datetime <- format(as.POSIXct(df.3$datetime, format = "%Y-%m-%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S") 

hour <- seq(0,60*60*24,by=60*60) 

datetime <- as.POSIXlt(hour, origin="1994-01-01") 

datetime <- format(as.POSIXct(hour, origin="1994-01-01"), "%Y-%m-%d %H:%M:%S" ) 

newdf <- merge(data.frame(datetime), df.3, all.x=TRUE, by="datetime") 
newdf 

다음은 스테이션의 누락 된 관측치를 동일한 스테이션의 이전 관측치 및 다음 관측치의 평균으로 대체하는 코드입니다. 매우 비효율적 인 중첩 된 for-loops을 사용하고 있습니다. 좀 더 효율적인 접근 방법을 찾으면 여기에 게시하는 것을 기억하려고 노력할 것입니다. 데이터 세트가 큰 경우이 중첩 된 for-loops은 실행하는 데 시간이 오래 걸릴 수 있습니다.

newdf2 <- newdf 

for(i in 1:nrow(newdf)) { 
    for(j in 2:ncol(newdf)) { 

      if(i == 1 &     is.na(newdf[i,j])) newdf2[i,j] = newdf[i+1,j] 
      if(i ==   nrow(newdf) & is.na(newdf[i,j])) newdf2[i,j] = newdf[i-1,j] 
      if(i > 1 & i < nrow(newdf) & is.na(newdf[i,j])) newdf2[i,j] = mean(c(newdf[i-1,j], newdf[i+1,j]), na.rm=TRUE) 
      if(is.nan(newdf2[i,j]))       newdf2[i,j] = NA 

    } 
} 

cbind(newdf, newdf2) 
+0

안녕하세요 마크 밀러, 고맙습니다. 그게 저를 위해 일하고 있습니다. 그러나 한 가지 질문이 있습니다. NA 대신 이전 및 다음 시계열 값의 평균을 가질 수있는 방법이 있습니까? –

+0

Hi Mark Miller, 둘 이상의 스테이션에서 수행 할 때 'fix.by (by.x, x)의 오류 : '오류 메시지가 표시됨 '숫자, 이름 또는 논리로 열을 지정해야 함 ". 이 문제를 해결하기 위해 내가 무엇을 제안합니까? 미리 감사드립니다. –

+0

@Wuletawu Abera 저는 위의 질문에 답하려고 노력해 왔습니다. –

0

rainfall_1 가정 및 rainfall_2는 POSIXct date 열 수 있습니다. 이제 데이터 프레임을 동물원 개체로 변환하고 세 번째 동물원 개체 z3 (예 : z2)을 예제에 추가하여 두 입력에 국한되지 않고 표시합니다.세 가지를 모두 병합하면 (동물원의 병합이 다중 경로 병합을 처리하여) zz이되며 결합 된 시간 시리즈가 제로 너비 격자 인 z0과 병합됩니다.

library(zoo) 

# set up input zoo objects 
z1 <- read.zoo(rainfall_1, FUN = identity) 
z2 <- read.zoo(rainfall_2, FUN = identity) 
z3 <- z2 

zz <- merge(z1, z2, z3) 
z0 <- zoo(, seq(start(zz), end(zz), by = "hour")) 
zout <- merge(zz, z0) 

이 제공 :

> zout 
        z1 z2 z3 
1994-01-01 00:00:00 0.0 0.0 0.0 
1994-01-01 01:00:00 NA 1.8 1.8 
1994-01-01 02:00:00 0.0 1.8 1.8 
1994-01-01 03:00:00 0.0 1.8 1.8 
1994-01-01 04:00:00 0.6 1.4 1.4 
1994-01-01 05:00:00 NA NA NA 
1994-01-01 06:00:00 2.6 1.8 1.8 
1994-01-01 07:00:00 3.2 NA NA 

당신은 너무 그 다른 시설을 활용하는 동물원이 탈퇴 할 수도 있지만 데이터 프레임으로 다시 설정하려는 경우 :

library(ggplot2) 
dfout <- fortify(zout) 
관련 문제