我有一个包含6列的数据框。第1列包含日期,第2列个体和第3至6列用于计算。
Date <- c(1, 1, 2, 2, 2, 3)
Ind <- c("a","a","a","b","c","c")
C <- c(5, 6, 5, 7, 8, 8)
D <- c(8, 8, 9, 9, 9, 9)
E <- c(8, 9, 11, 10, 9, 7)
F <- c(5, 6, 8, 5, 7, 4)
df <- data.frame(Date, Ind, C, D, E, F)
我想进行一次计算(如(C-E)+(D-F)(在现实生活中,这些是坐标,我正在计算距离,但这不是我现在的问题所在。)
我想执行存储在新列(G)中的计算,我在第1天使用C列和E列的值与从第+天开始的列E和F的值之间有1天的差异1为同一个人。
我不确定是否应该使用循环或应用函数。这是我到目前为止所尝试的,基于这个线程的矢量化操作和子集:Loop over rows of dataframe applying function with if-statement
df$G <- NA
df[!(df$Date ==(df$Date+1)), "G"] <- ((C-E)+(D-F))
这样可行,但它对同一行(C,D,E,F全部来自同一行)的坐标进行计算。我知道为什么会这样做,因为我没有说明从哪一行取坐标。需要从Date = Date的行获取C和D,并从Date =(Date + 1)的行中获取E和F. 我意识到了,但我无法理解如何做到这一点。
继续这条路线?在for循环中做它?使用应用功能?
答案 0 :(得分:0)
dplyr
包提供了非常好的lag
和lead
功能。
> library(dplyr)
> df %>% mutate(G = C + D + lead(E,1) + lead(F,1))
Date Ind C D E F G
1 1 a 5 8 8 5 28
2 1 a 6 8 9 6 33
3 2 a 5 9 11 8 29
4 2 b 7 9 10 5 32
5 2 c 8 9 9 7 28
6 3 c 8 9 7 4 NA
G是最后一行的NA
,因为没有下一个日期值。
正如其他人所提到的,看起来您的示例数据有Ind==a
的两个日期。在这种情况下,您可能需要小心处理领先/滞后。
如果这样做是有道理的,你可以先做好聚合,然后再做领先/滞后。
df %>% group_by(Date,Ind) %>%
summarise(C=mean(C),D=mean(D),E=mean(E),F=mean(F)) %>%
ungroup %>%
mutate(G = C + D + lead(E,1) + lead(F,1))
产生:
Date Ind C D E F G
1 1 a 5.5 8 8.5 5.5 32.5
2 2 a 5.0 9 11.0 8.0 29.0
3 2 b 7.0 9 10.0 5.0 32.0
4 2 c 8.0 9 9.0 7.0 28.0
5 3 c 8.0 9 7.0 4.0 NA