创建包含具有相同ID的先前值的新列

时间:2016-08-02 16:36:35

标签: r

我的数据看起来像这样,已经排序了:

> dput(df)
structure(list(id = c(1, 2, 3, 3, 2, 2, 1), x = c(20, 40, 70, 
70, 80, 40, 70)), .Names = c("id", "x"), row.names = c(NA, -7L
), class = "data.frame")

> df
  id  x
1  1 20
2  2 40
3  3 70
4  3 70
5  2 80
6  2 40
7  1 70

我需要创建一个新列,其中包含x的前一个值id。所以结果应该是:

> df
  id  x old_x
1  1 20    70
2  2 40    80
3  3 70    70
4  3 70    NA
5  2 80    40
6  2 40    NA
7  1 70    NA

我可以这样做:

for (i in 1:nrow(df)){
  id0 = df$id[i]
  j = i + match(id0 , df$id[i+1:nrow(df)])
  df$old_x[i] = df$x[j]
}

但它太慢了。最好的方法是什么?

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

使用dplyr

library(dplyr)
df %>% group_by(id) %>% mutate(old_x = lead(x))

#Source: local data frame [7 x 3]
#Groups: id [3]

#     id     x old_x
#  <dbl> <dbl> <dbl>
#1     1    20    70
#2     2    40    80
#3     3    70    70
#4     3    70    NA
#5     2    80    40
#6     2    40    NA
#7     1    70    NA

答案 1 :(得分:2)

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(df)),按'id'分组,我们将':=中的lead值分配给'old_x ”。这应该非常快,因为我们正在分配。

library(data.table)
setDT(df)[,old_x := shift(x, type = "lead") , by = id]
df
#   id  x old_x
#1:  1 20    70
#2:  2 40    80
#3:  3 70    70
#4:  3 70    NA
#5:  2 80    40
#6:  2 40    NA
#7:  1 70    NA

答案 2 :(得分:1)

以下是包含avetail的基本R方法:

df$old_x <- ave(df$x, df$id, FUN=function(i) c(tail(i, -1), NA))

df
  id  x old_x
1  1 20    70
2  2 40    80
3  3 70    70
4  3 70    NA
5  2 80    40
6  2 40    NA
7  1 70    NA