RowDiff类型函数,保留“;第1行“;作为每个组的参考行

RowDiff类型函数,保留“;第1行“;作为每个组的参考行,r,R,假设我有一个带有分组变量的简单数据框,每个组有三个X: df<-data.frame(grp=rep(letters[1:3],each=3), x=rnorm(9)) grp x 1 a 1.9561455 2 a -2.3916438 3 a 0.7267603 4 b -0.8794693 5 b -0.3089820 6 b -1.7228825 7 c -0.3964017 8 c -0.6

假设我有一个带有分组变量的简单数据框,每个组有三个X:

df<-data.frame(grp=rep(letters[1:3],each=3),
               x=rnorm(9))

  grp          x
1   a  1.9561455
2   a -2.3916438
3   a  0.7267603
4   b -0.8794693
5   b -0.3089820
6   b -1.7228825
7   c -0.3964017
8   c -0.6237301
9   c -0.1522535
我通过这种方式做到了:

rowOne<-df %>% group_by(grp) %>% filter(row_number()==1)
names(rowOne)[2]<-"x_initial"
df %>% left_join(rowOne) %>% mutate(xdiff=x-x_initial)
但是,显然,这不是正确的函数。有没有一个函数我没有遇到过,或者有一个更简单的方法来编程R来完成这个任务


谢谢

可以使用
data.table
dplyr
base R
方法,通过另一列分组的列中的第一个值来计算列之间的差异

如果我们对单个列执行此操作,则compact data.table方法是一个选项。我们将'data.frame'转换为'data.table'(
setDT(df)
),按分组列('grp')分组,我们得到列('x')和该列中第一个值(
x[1L]
)之间的差值。注意,我使用了整数表示,即1L。它也可以通过简单地使用
x[1]来工作
。在某些情况下,整数可能会快一点)

或者使用
dplyr
的类似选项是从左到右管道(
%%>%%
)参数,即使用数据集('df'),然后我们按“grp”分组,并使用
mutate
创建一个新列。请注意,在
dplyr
中有一个
first
功能来选择第一个观测值。它还有其他参数(
?first

或者@David Arenburg建议的
base R
选项

df$xdiff <- with(df, ave(x, grp), FUN = function(x) x - x[1L])
或者使用
data.table
,我们可以通过赋值(
:=
)来创建新列。在这里,我们使用
lappy
(.SD是DataTable的
子集)循环考虑中的列,并获得按“grp”分组的差异

nm1 <- setdiff(names(df1), 'grp')
setDT(df1)[, paste0(nm1, 'diff') :=lapply(.SD, function(x) x-x[1L]), grp]

nm1和
with(df,ave(x,grp),FUN=函数(x)x-x[1L])
ofcourse@AndrewTaylor在
first
中有一个选项
order\u by
。我以前从未用过。
library(data.table)
setDT(df)[, xdiff:=x-x[1L] , by = grp]
library(dplyr)
df %>%
  group_by(grp) %>%
  mutate(xdiff= x- first(x)) 
df$xdiff <- with(df, ave(x, grp), FUN = function(x) x - x[1L])
df1 %>% 
  group_by(grp) %>%
  mutate_each(funs(.-first(.))) %>%
  setNames(., c(names(df1)[1L], paste0(names(df1)[-1L], 'diff'))) %>% 
  ungroup() %>%
  select(-grp) %>%
  bind_cols(df1, .)
nm1 <- setdiff(names(df1), 'grp')
setDT(df1)[, paste0(nm1, 'diff') :=lapply(.SD, function(x) x-x[1L]), grp]
set.seed(24)
df1 <- cbind(df, y= rnorm(9))