2017-03-08 1 views
0

저는 데이터 프레임의 여러 열에 롤링 평균을 적용하려고 시도했습니다. 각 열에는 여러 개인의 데이터가 포함되어 있습니다. 나는 RcppRoll 패키지에서 roll_mean을 사용하여 성공했으며 lapply. 더미 데이터 프레임과 출력을 사용하는 예제를 아래에 포함 시켰습니다.R에서 roll_mean을 사용할 때 재활용을 피하는 방법은 무엇입니까?

x <- rnorm(20,1); 
    y <- rnorm(20,2); 
    z <- rnorm(20,3); 
    ID <- rep(1:2, each=10); 

    mydf <- data.frame(ID, x, y, z); 

    vars <- c("x", "y", "z"); 

setDT(mydf)[, paste0(vars, "_", "mean") := lapply(.SD, function(x) roll_mean(x, n=3, na.rm = TRUE)), .SDcols = vars, by = ID] 

mydf 

     ID   x   y   z x_mean y_mean z_mean 
    1: 1 0.34457704 1.9580361 2.6458335 1.2515642 1.8307447 2.569645 
    2: 1 1.41839352 2.0697324 1.8495358 1.7012511 1.7248261 2.988908 
    3: 1 1.99172192 1.4644657 3.2135652 1.8455087 1.7165419 3.184736 
    4: 1 1.69363783 1.6402801 3.9036227 1.5002658 2.1512764 3.289555 
    5: 1 1.85116646 2.0448798 2.4370206 0.9775842 3.1215589 2.563110 
    6: 1 0.95599300 2.7686692 3.5280206 0.8477701 3.4576141 3.106095 
    7: 1 0.12559300 4.5511275 1.7242892 0.9450234 3.5134499 3.020176 
    8: 1 1.46172438 3.0530454 4.0659766 0.9080677 3.0100022 3.371839 
    9: 1 1.24775283 2.9361768 3.2702614 1.2515642 1.8307447 2.569645 
    10: 1 0.01472603 3.0407845 2.7792776 1.7012511 1.7248261 2.988908 
    11: 2 -0.91146047 2.5898074 2.0328348 0.4314443 1.2688530 2.477879 
    12: 2 0.48183559 1.8230335 2.6910075 1.2689767 0.9650435 2.544006 
    13: 2 1.72395769 -0.6062819 2.7097949 0.8747931 1.2273766 1.974265 
    14: 2 1.60113680 1.6783790 2.2312143 0.2579207 1.6945497 2.233321 
    15: 2 -0.70071522 2.6100328 0.9817857 0.1162224 2.0928536 2.606608 
    16: 2 -0.12665946 0.7952374 3.4869635 1.3884888 2.1063817 2.986786 
    17: 2 1.17604187 2.8732906 3.3510742 2.0557599 2.2701173 3.178248 
    18: 2 3.11608400 2.6506171 2.1223190 1.5553274 2.3987061 3.015501 
    19: 2 1.87515393 1.2864441 4.0613513 0.4314443 1.2688530 2.477879 
    20: 2 -0.32525560 3.2590570 2.8628313 1.2689767 0.9650435 2.544006 

가 출력 테이블 (mydf) 평균 매개 변수가 lapply 문장의 일부로서 생성되고, 상기 회전 수단은 각각의 ID에 대하여 계산되었다에서 볼 수 있듯이. 그러나 roll_mean 함수는 각 개별 ID에 대해 10 개의 원시 값에서 8 개의 값을 생성하기 때문에 롤링 평균 함수는 데이터 프레임을 채우기 위해 결과를 재활용했습니다. 그것은 재활용을 사용하여 각 ID에 대해 마지막 두 행을 채 웁니다. 실제 데이터는 시계열 데이터이므로 결과를 재활용하지 않으려 고합니다. X_mean 열의 시작 부분에 원시 x 값을 추가하여 3 포인트 롤링 평균을 생성하기에 충분한 원시 데이터가있는 지점까지 재활용을 피하고 싶습니다.

roll_mean 또는 이와 유사한 기능을 사용하지 않고 재활용을 피하는 방법에 대한 게시물을 (SO와 Google에서) 검색해 보았습니다.

roll_mean 함수에서 재활용을 피하기 위해 예제에서 처음 두 행을 채우는 방법을 아는 사람이 있습니까?

감사합니다.

+0

'RcppRoll :: roll_mean()'에는'fill' 인수가 있어야하며 그곳에는'NA'를 사용하고 나중에 값을 복사하십시오. 'x','y','z' 칼럼을 사용합니다. –

답변

0

전체 솔루션 :

x <- rnorm(20,1); 
y <- rnorm(20,2); 
z <- rnorm(20,3); 
ID <- rep(1:2, each=10); 

mydf <- data.table(ID, x, y, z); # Changed to dt here 

vars <- c("x", "y", "z"); 

# fill = NA and align = 'right' 
mydf[, paste0(vars, "_", "mean") := lapply(.SD, function(x) RcppRoll::roll_mean(x, n = 3, na.rm = TRUE, fill = NA, align = 'right')), .SDcols = vars, by = ID] 

mydf 

#  ID   x   y  z x_mean y_mean z_mean 
# 1: 1 0.3735462 2.9189774 2.835476  NA  NA  NA 
# 2: 1 1.1836433 2.7821363 2.746638  NA  NA  NA 
# 3: 1 0.1643714 2.0745650 3.696963 0.5738536 2.591893 3.093026 
# 4: 1 2.5952808 0.0106483 3.556663 1.3144318 1.622450 3.333422 
# 5: 1 1.3295078 2.6198257 2.311244 1.3630533 1.568346 3.188290 
# ... 

mydf[is.na(x_mean), c(paste0(vars, "_", "mean")) := mget(paste0(vars))] 

mydf 

#  ID   x   y  z x_mean y_mean z_mean 
# 1: 1 0.3735462 2.9189774 2.835476 0.3735462 2.918977 2.835476 
# 2: 1 1.1836433 2.7821363 2.746638 1.1836433 2.782136 2.746638 
# 3: 1 0.1643714 2.0745650 3.696963 0.5738536 2.591893 3.093026 
# 4: 1 2.5952808 0.0106483 3.556663 1.3144318 1.622450 3.333422 
# 5: 1 1.3295078 2.6198257 2.311244 1.3630533 1.568346 3.188290 
# ... 

편집 : mydf

누락 된 부분도 조금 채울 수는 "스마트"방법은, 롤을 사용하여 즉 1에 의해 작은 창으로 의미 모든 반복 :

for (n_inner in n_roll:1) { 
    mydf[!complete.cases(mydf), 
     paste0(vars, "_", "mean") := lapply(
     .SD, function(x) RcppRoll::roll_mean(x, n = n_inner, na.rm = TRUE, fill = NA, align = 'right')), .SDcols = vars, by = ID] 
    } 

#  ID   x   y  z x_mean y_mean z_mean 
# 1: 1 0.3735462 2.9189774 2.835476 0.3735462 2.918977 2.835476 <- Values from x, y and z 
# 2: 1 1.1836433 2.7821363 2.746638 0.7785948 2.850557 2.791057 <- roll_mean with window 2 
# 3: 1 0.1643714 2.0745650 3.696963 0.5738536 2.591893 3.093026 <- roll_mean with window 3 
# 4: 1 2.5952808 0.0106483 3.556663 1.3144318 1.622450 3.333422 <- as above 
# 5: 1 1.3295078 2.6198257 2.311244 1.3630533 1.568346 3.188290 
# ... 
+0

mydf [! complete.cases (mydf), c (paste0 (vars, "_", "mean")) : = mget (paste0 (vars))]'를 사용할 수 있습니다. –

+0

감사합니다. m-dz. 귀하의 솔루션은 완벽하게 작동했습니다. – tregnog

관련 문제