2014-02-18 18 views
3

給定一個數據幀如下:在R中,如何根據前一行(或後一行)的變化爲變量設置一個值?

id<-c(1,1,1,1,1,1,2,2,2,2,2,2) 
t<-c(6,8,9,11,12,14,55,57,58,60,62,63) 
p<-c("a","a","a","b","b","b","a","a","b","b","b","b") 
df<-data.frame(id,t,p) 

row id t p 
1 1 6 a 
2 1 8 a 
3 1 9 a 
4 1 11 b 
5 1 12 b 
6 1 14 b 
7 2 55 a 
8 2 57 a 
9 2 58 b 
10 2 60 b 
11 2 62 b 
12 2 63 b 

我想創建一個新的變量「TA」,使得TA的值是:

  1. 零的行,其中「P」的變化從a到b對於給定的ID(行4和9)(我可以做的)
  2. 在每個唯一的id中,當p是'a'時,ta的值應該從零開始倒數有問題的行和它上面的行。例如,對於第3行,ta的值應爲0 - (11-9)= -2。
  3. 在每個唯一的ID中,當p是'b'時,ta的值應該從0開始從所述行和它下面的行之間的t變化中算起。例如,對於行5,Ta的值應該爲0 +(12-11)= 1

因此,完成時,數據幀應如下所示:

row id t p ta 
1 1 6 a -5 
2 1 8 a -3 
3 1 9 a -2 
4 1 11 b 0 
5 1 12 b 1 
6 1 14 b 3 
7 2 55 a -3 
8 2 57 a -1 
9 2 58 b 0 
10 2 60 b 2 
11 2 62 b 4 
12 2 63 b 5 

我我一直在玩循環和cumsum()和head()和tail(),並且在條件求和工作中不能完全做到這種id /內。還有一些關於使用前一行或後一行值的其他問題,但我無法完全重塑這些技術在這裏的工作。你的想法非常感謝。

+0

你的算法還不清楚。你是如何在第一排中得到-5和在第七排中得到-3的? – Thomas

+0

對於第1行,-5 = -3 - (8 - 6)。即,ta1 = ta2-(t2-t1)。對於第7行,-3 = -1 - (57-55)。即,ta7 = ta8-(t8-t7)。這更清楚嗎?如果沒有,請讓我知道,我會提供另一個例子或嘗試以不同的方式構建問題/答案。 – seehuus

回答

2

你在這裏。這是一種拆分應用組合策略,將所有內容打破id,建立p=='a'p=='b'之間的轉換點,然後減去高於和低於該值的值。它只適用於您的數據實際按照您在此處顯示的方式排序的情況。

do.call('rbind', 
lapply(split(df, id), function(x) { 
    # save values of `0` at transition points in `p` 
    x <- cbind.data.frame(x, ta=ifelse(c(0,diff(as.numeric(as.factor(x$p))))==1, 0, NA)) 

    # identify indices for those points 
    w <- which(x$ta==0) 

    # handle `ta` values for `p=='b'` 
    x$ta[(w+1):nrow(x)] <- x$ta[w] + (x$t[(w+1):nrow(x)] - x$t[w]) 

    # handle `ta` values for `p=='a'` 
    x$ta[1:(w-1)] <- x$ta[w] - (x$t[w] - x$t[1:(w-1)]) 

    return(x) 
}) 
) 

結果:

 id t p ta 
1.1 1 6 a -5 
1.2 1 8 a -3 
1.3 1 9 a -2 
1.4 1 11 b 0 
1.5 1 12 b 1 
1.6 1 14 b 3 
2.7 2 55 a -3 
2.8 2 57 a -1 
2.9 2 58 b 0 
2.10 2 60 b 2 
2.11 2 62 b 4 
2.12 2 63 b 5 
+0

太棒了!非常感謝你! – seehuus

相關問題