2014-11-03 3 views
0

이것은 이전에 게시 한 질문에 대한 질문입니다 (자세한 내용은 Sum over rows with multiple changing conditions R data.table 참조). 지난 5 년 동안 3 명의 피험자가 몇 번이나 이벤트를 경험했는지 계산하고 싶습니다. 따라서 zoo 패키지의 rollapply을 사용하여 롤링 윈도우를 합산했습니다. 이것은 5 년 전의 경험이 1 년 전의 경험 (같은 가중치)만큼 중요하다고 가정하므로 합계를 입력하는 경험에 시간 상실을 포함시키고 자합니다. 이것은 기본적으로 5 년 전의 경험이 1 년 전의 경험과 동일한 가중치를 가진 합계에 포함되지 않는다는 것을 의미합니다.시간이 지남에 따라 행 합계 (rollapply)

필자는 필자가 연령에 따른 감쇠를 포함하고 싶다. (비록 다른 응용 프로그램이 제곱근이나 제곱 같은 더 빠르거나 느린 감쇠가 가능할지라도). 예를 들어

내가 다음 데이터 (나는 명확성을 위해 이전 데이터 구축)에 있다고 가정 할 수 있습니다 :

mydf <- data.frame (Year = c(2000, 2001, 2002, 2004, 2005, 
         2007, 2000, 2001, 2002, 2003, 
         2003, 2004, 2005, 2006, 2006, 2007), 
       Name = c("Tom", "Tom", "Tom", "Fred", "Gill", 
         "Fred", "Gill", "Gill", "Tom", "Tom", 
         "Fred", "Fred", "Gill", "Fred", "Gill", "Gill")) 

# Create an indicator for the experience 
mydf$Ind <- 1 

# Load require packages 
library(data.table) 
library(zoo) 

# Set data.table 
setDT(mydf) 
setkey(mydf, Name,Year) 

# Perform cartesian join to calculate experience. I2 is the new experience indicator 
m <- mydf[CJ(unique(Name),seq(min(Year)-5, max(Year))),allow.cartesian=TRUE][, 
     list(Ind = unique(Ind), I2 = sum(Ind,na.rm=TRUE)), 
     keyby=list(Name,Year)] 

# This is the approach I have been taking so far. Note that is a simple rolling sum of I2 
m[,Exp := rollapply(I2, 5, function(x) sum(head(x,-1)), 
       align = 'right', fill=0),by=Name] 

그래서 질문 지금, 나는이 계산으로 나이에 따라 부패를 포함하는 방법. 이것을 모형화하려면 경험의 나이를 경험치로 나눌 필요가 있습니다.

m[,Exp_age := rollapply(I2, 5, function(x) sum(head(x,-1)/(tail((Year))-head(Year,-1))), 
        align = 'right', fill=0),by=Name] 

을하지만 그것은 작동하지 않습니다

나는이 라인을 따라 뭔가를 사용하여 작업을 얻기 위해 노력 해왔다. 내 주요 문제는 경험의 권리를 얻을 수 없다는 것입니다. 그래서 나이별로 나누어 볼 수 있습니다. 그 결과 모든 포인터는 크게 감상 할 수

myres <- data.frame(Name = c("Fred", "Fred", "Fred", "Fred", "Fred", 
         "Gill", "Gill", "Gill", "Gill", "Gill", "Gill", 
         "Tom", "Tom", "Tom", "Tom", "Tom"), 
       Year = c(2003, 2004, 2004, 2006, 2007, 2000, 2001, 2005, 
         2005, 2006, 2007, 2000, 2001, 2002, 2002, 2003), 
       Ind = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
       Exp = c(0, 1, 1, 3, 4, 0, 1, 1, 1, 2, 3, 0, 1, 2, 2, 4), 
       Exp_age = c(0, 1, 1, 1.333333333, 1.916666667, 0, 1, 0.45, 
          0.45, 2.2, 2, 0, 1, 1.5, 1.5, 2.833333333)) 

아래 myresdata.frameExp_age 열처럼 보일 것입니다!

답변

2

정확하게 이해했다면 을 width=5으로 사용하려고합니다. 단순한 합계가 아니라 가중 합계를 사용하려고합니다. 가중치는 5 년 창에 상대적인 경험의 나이입니다. 나는 이것을 할 것이다 : 먼저 data.table에 키를 설정하여 순서가 적절히 증가하고 Name 일 때, x 변수의 마지막 항목이 가장 젊고 첫 번째 항목이 가장 오래되었다는 것을 알고있다. (코드에서 이렇게한다. 이미). 나는 체중이 (가장 젊거나 가장 큰 체중을지기 위해 가장 어린 것이지만) 어느 방향으로 가고 싶은지를 말할 수는 없다. 그러나 점을 얻는다 :

setkey(m, Name, Year) 
my_fun = function(x) { w = 1:length(x); sum(x*w)} 
m[,Exp_age:=rollapply(I2, width=5, by=1, fill=NA, FUN=my_fun, by.column=FALSE, align="right") ,by=Name] 
+0

고맙습니다. 당신이 옳습니다. 나는 그것이 성취하려고 노력하는 것입니다. 함수를 my_fun = function (x) {w = length (x) : 1; sum (x/w)}'올바른 값 (또는 적어도 일부)을 반환하는 것처럼 보이지만 Exp_age 열이 예상대로 정렬되지 않습니다. 또한 다음과 같은 3 개의 경고 메시지가 나타납니다. '1 : In [.data.table'' (m,,''= =''(Exp_age, rollapply (I2, width = 5, by = 1, : 9 'Exp_age'컬럼에있는 크기 13의 그룹 1에 할당 할 항목. (4 항목의 남은 부분을 재활용하여 재활용 함.) (계속 다음 주석) – Rkook

+0

'2 :'[.data.table'' (m,,' 'Exp_age, rollapply (I2, width = 5, by = 1, : 'Exp_age '열에 크기 13의 그룹 2에 9 개의 항목이 제공되었습니다 (나머지 4 항목은 재활용 됨). 3 : {.data.table'' (m,,''= =''(Exp_age, rollapply (I2, width = 5, by = 1, : 크기 13의 그룹 3에 9 개의 아이템이 배정되었습니다. 'Exp_age'열 (나머지 4 항목을 남겨두고 재활용 됨) .' – Rkook

+0

무슨 일이 벌어지고있는 가를 발견했습니다. 'partial = TRUE'을 허용해야합니다. 코드는 다음과 같습니다.'m [, Exp_age : = rollapply (I2, width = 5, by = 1, FUN = my_ 재미, by.column = FALSE, align = "right", partial = TRUE), by = Name]'.그런 다음 원하는 결과를 얻으려면 경험 변수를 지연해야합니다 (한 번에 할 수는 없지만). – Rkook

관련 문제