矢量化或for循环或应用函数?

时间:2014-12-02 05:24:30

标签: r

我有一个包含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循环中做它?使用应用功能?

1 个答案:

答案 0 :(得分:0)

dplyr包提供了非常好的laglead功能。

> 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
相关问题