我是R的新手并且学习基本的东西。我在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
我想要的是根据特定的user_id,mth_id计算每个controller_id的col_values的差异,并仅显示随着mth_id的增加而减少的col_values。
例如:对于controller_id = X,我们有3个user_id作为A,B,C用于两个不同的mth_id。代码应该为所有3个users_id计算m__id 1398和1393的col_val1之间的差异,并且如果该差异是&lt; 0然后我想要像
这样的输出Col_val1 for controller_id 'X', user_id 'A' has decreased from 5 to 3
如果给定的controller_id没有关联的user_id,那么它应该计算controller_id本身之间的列值差异。
理想情况下,我希望将这些输出存储在列表/数据框中以供以后使用。 此外,代码将运行约。数据框中有900列。
我正在将除controller_id,User_id,mth_id之外的所有列转换为数字字段,然后我使用' data.table '计算每个user_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
但是,我想在Controller_id级别实现类似的功能。我知道工作流程如下 - 选择一个控制器ID - 看看我们是否有user_id。如果我们有,那么我们比较1393和1398的user_id列值并查看差异。但不知何故,我无法对此进行编码。
非常感谢任何帮助。
答案 0 :(得分:0)
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
如果这是您想要的,最后两列是差异,因为最终结果是data.frame
很容易改变。