基于列值的R中的行之间的差异

基于列值的R中的行之间的差异,r,dataframe,apply,R,Dataframe,Apply,我是新手,学习基础知识。我在R中有一个数据帧,其中包含像controller_id、user_id、mth_id、col_val1到col_val100这样的列 df <- data.frame('controller_id' = c('X','X','X','X','X','X','Y','Y','Y','Y','Y','Y','Z','Z'), 'user_id'=c('A','B','C','A','B','C','P','Q','R','P','Q','R',NA,NA), 'mt

我是新手,学习基础知识。我在R中有一个数据帧,其中包含像controller_id、user_id、mth_id、col_val1到col_val100这样的列

df <- data.frame('controller_id' = c('X','X','X','X','X','X','Y','Y','Y','Y','Y','Y','Z','Z'),
'user_id'=c('A','B','C','A','B','C','P','Q','R','P','Q','R',NA,NA),
'mth_id'=c('1393','1393','1393','1398','1398','1398','1393','1393','1393','1398','1398','1398','1393','1398'),
'col_val1' = c(5,4,6,3,1,10,12,15,18,13,19,1,5,2),
'col_val2'=c(8,12,9,2,12,5,7,9,11,4,0,7,10,5))

> df
   controller_id user_id mth_id col_val1 col_val2
1              X       A   1393        5        8
2              X       B   1393        4       12
3              X       C   1393        6        9
4              X       A   1398        3        2
5              X       B   1398        1       12
6              X       C   1398       10        5
7              Y       P   1393       12        7
8              Y       Q   1393       15        9
9              Y       R   1393       18       11
10             Y       P   1398       13        4
11             Y       Q   1398       19        0
12             Y       R   1398        1        7
13             Z    <NA>   1393        5       10
14             Z    <NA>   1398        2        5
如果给定控制器id没有关联的用户id,则应计算控制器id本身之间的列值差

理想情况下,我希望将这些输出存储在列表/数据框中,以供以后使用。 此外,该代码将针对数据框中存在的约900列运行

我正在将除controller\u id、User\u id、mth\u id之外的所有列转换为数字字段,然后使用“data.table”计算每个User\u id的结果(一次只取一列)

> df[,4:ncol(df)] <- sapply(df[,4:ncol(df)],as.numeric)
> result_col1 <- setDT(df)[,val_diff := col_val1 - lag(col_val1,1L), by=user_id]

> result_col1
    controller_id user_id mth_id col_val1 col_val2 val_diff
  1:             X       A   1393        5        8       NA
  2:             X       B   1393        4       12       NA
  3:             X       C   1393        6        9       NA
  4:             X       A   1398        3        2       -2
  5:             X       B   1398        1       12       -3
  6:             X       C   1398       10        5        4
  7:             Y       P   1393       12        7       NA
  8:             Y       Q   1393       15        9       NA
  9:             Y       R   1393       18       11       NA
 10:             Y       P   1398       13        4        1
 11:             Y       Q   1398       19        0        4
 12:             Y       R   1398        1        7      -17
 13:             Z      NA   1393        5       10       NA
 14:             Z      NA   1398        2        5       -3
>df[,4:ncol(df)]结果\u col1结果\u col1
控制器id用户id mth id列值1列值2列值差异
1:X A 1393 5 8 NA
2:X B 1393 4 12 NA
3:X C 1393 6 9 NA
4:X1398 3 2-2
5:X1398112-3
6:X C 1398 10 5 4
7:Y P 1393 12 7 NA
8:Y Q 1393 15 9 NA
9:Y R 1393 18 11 NA
10:Y P 1398 13 4 1
11:Y Q 1398 19 0 4
12:Y R 1398 1 7-17
13:Z NA 1393 5 10 NA
14:Z NA 1398 2 5-3
然而,我希望在控制器id级别实现类似的功能。我知道这样的工作流程——选择一个控制器Id——看看里面是否有用户Id。如果有,那么我们将比较1393和1398的用户id列值,并查看差异。但不知何故,我无法编写此代码

任何帮助都将不胜感激。

Whit base R:

usplit<-with(df,split(df,controller_id))

rsl<-lapply(usplit,function(dt){
  do.call("rbind",by(dt,factor(dt[,"user_id"],exclude = NULL),function(vt){
    n1=1:nrow(vt)
    cbind(vt,rbind(NA,vt[n1[-1],4:5]-vt[n1[-length(n1)],4:5]))
  }))
})

do.call("rbind",rsl)

> do.call("rbind",rsl)
        controller_id user_id mth_id col_val1 col_val2 col_val1 col_val2
X.A.1               X       A   1393        5        8       NA       NA
X.A.4               X       A   1398        3        2       -2       -6
X.B.2               X       B   1393        4       12       NA       NA
X.B.5               X       B   1398        1       12       -3        0
X.C.3               X       C   1393        6        9       NA       NA
X.C.6               X       C   1398       10        5        4       -4
Y.P.7               Y       P   1393       12        7       NA       NA
Y.P.10              Y       P   1398       13        4        1       -3
Y.Q.8               Y       Q   1393       15        9       NA       NA
Y.Q.11              Y       Q   1398       19        0        4       -9
Y.R.9               Y       R   1393       18       11       NA       NA
Y.R.12              Y       R   1398        1        7      -17       -4
Z.NA.13             Z    <NA>   1393        5       10       NA       NA
Z.NA.14             Z    <NA>   1398        2        5       -3       -5

usplitSorry@agenis没有提及我之前尝试过的内容。我已经用我执行的几个步骤更新了我的问题。有人能在这方面帮助我吗@哈克-R
usplit<-with(df,split(df,controller_id))

rsl<-lapply(usplit,function(dt){
  do.call("rbind",by(dt,factor(dt[,"user_id"],exclude = NULL),function(vt){
    n1=1:nrow(vt)
    cbind(vt,rbind(NA,vt[n1[-1],4:5]-vt[n1[-length(n1)],4:5]))
  }))
})

do.call("rbind",rsl)

> do.call("rbind",rsl)
        controller_id user_id mth_id col_val1 col_val2 col_val1 col_val2
X.A.1               X       A   1393        5        8       NA       NA
X.A.4               X       A   1398        3        2       -2       -6
X.B.2               X       B   1393        4       12       NA       NA
X.B.5               X       B   1398        1       12       -3        0
X.C.3               X       C   1393        6        9       NA       NA
X.C.6               X       C   1398       10        5        4       -4
Y.P.7               Y       P   1393       12        7       NA       NA
Y.P.10              Y       P   1398       13        4        1       -3
Y.Q.8               Y       Q   1393       15        9       NA       NA
Y.Q.11              Y       Q   1398       19        0        4       -9
Y.R.9               Y       R   1393       18       11       NA       NA
Y.R.12              Y       R   1398        1        7      -17       -4
Z.NA.13             Z    <NA>   1393        5       10       NA       NA
Z.NA.14             Z    <NA>   1398        2        5       -3       -5