引用data.frame的先前行以计算R中的新列

时间:2014-12-01 15:52:21

标签: r for-loop plyr

我正在尝试计算在不同巢穴中对雏鸡的访问之间的体重变化。这需要R在当前行中查找嵌套代码,找到上次访问该嵌套的时间,并从当前访问中减去上次访问时的权重。对于第一次访问每个巢,我想输出当前的重量(即好像之前的,不存在的访问的重量为零)。

我的数据形式如下:

Nest   <- c(a,b,c,d,e,c,b,c)
Weight <- c(2,4,3,3,2,6,8,10)
df <- data.frame(Nest, Weight)

所以这里所需的输出是:

Change <- c(2,4,3,3,2,3,4,4)

我已经实现了一次所需的输出,通过子集化到单个嵌套并使用for循环:

tmp <- subset(df, Nest == "a")
tmp$change <- tmp$Weight
for(x in 2:(length(tmp$Nest))){
tmp$change[x] <- tmp$Weight[(x)] - tmp$Weight[(x-1)]
}

但是当我尝试将其融入ddply时

df2 <- ddply(df, "Nest", function(f) {
  f$change <- f$Weight
  for(x in 2:(length(f$Nest))){
    f$change <- f$Weight[(x)] - f$Weight[(x-1)]
  }
})

输出给出一个空白的data.frame(0个隐含0个变量)。

我是以正确的方式接近这个但是错误的代码?或者有更好的方法吗?

提前致谢!

2 个答案:

答案 0 :(得分:4)

试试这个:

library(dplyr)
df %>% group_by(Nest) %>% mutate(Change = c(Weight[1], diff(Weight)))

或只是R

的基础
transform(df, Change = ave(Weight, Nest, FUN = function(x) c(x[1], diff(x))))

答案 1 :(得分:1)

这是一个data.table解决方案。对于大型数据集,这可能会更快。

library(data.table)
setDT(df)[,Change:=c(Weight[1],diff(Weight)),by=Nest]
df
#    Nest Weight Change
# 1:    a      2      2
# 2:    b      4      4
# 3:    c      3      3
# 4:    d      3      3
# 5:    e      2      2
# 6:    c      6      3
# 7:    b      8      4
# 8:    c     10      4