在R中按组计算第一差分

3
我希望有人能够帮我按组计算分数的第一差异。我知道这应该是一个简单的过程,但出于某种原因,我做起来有些困难.....天哪
下面是一个数据框示例:
score <- c(10,30,14,20,6)

group <- c(rep(1001,2),rep(1005,3))

df <- data.frame(score,group)

> df 
  score group
1    10  1001
2    30  1001
3    14  1005
4    20  1005
5     6  1005

这是我期望得到的输出结果。
1   NA
2   20
3   NA  
4    6
5  -14

感谢您的提前帮助。
4个回答

14

这是使用基础 R 的一种方法

df$diff <- unlist(by(df$score , list(df$group) , function(i) c(NA,diff(i))))
或者
df$diff <- ave(df$score , df$group , FUN=function(i) c(NA,diff(i)))


或者使用data.table - 对于较大的数据框,这将更加高效。

library(data.table)
dt <- data.table(df)
setkey(dt,group)
dt[,diff:=c(NA,diff(score)),by=group]

谢谢,这个很好用。我使用了基本的R语法,但需要安装data.table。 - Richard

9

使用dplyr的另一种方法:

library(dplyr)

score <- c(10,30,14,20,6)
group <- c(rep(1001,2),rep(1005,3))
df <- data.frame(score,group)

df %>%
  group_by(group) %>%
  mutate(first_diff = score - lag(score))

1
虽不完全符合您的要求,但 'plyr' 包中的 ddply 函数可以按组计算差异。
library(plyr)
out<-ddply(df,.(group),summarize,d1=diff(score,1))

谢谢Steve,我尝试了plyr,但它在我的电脑上运行得非常缓慢。 - Richard

0

这应该可以完成任务,尽管它使用循环而不是 apply 函数,所以代码清晰度/效率可能还有提高的空间。

out = numeric()
#out[1] will always be NA
out[1] = NA
for(i in 2:nrow(df)){
  if(df$group[i]==df$group[(i-1)]){
    out[i]=df$score[i]-df$score[(i-1)]
  } 
  else {
    out[i]=NA
  }
}
out
[1]  NA  20  NA   6 -14

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接