我在R中安排了这样的数据:
indv time val
A 6 5
A 10 10
A 12 7
B 8 4
B 10 3
B 15 9
Run Code Online (Sandbox Code Playgroud)
对于每次每个人(indv),我想val从初始时间计算值()的变化.所以我最终得到这样的东西:
indv time val val_1 val_change
A 6 5 5 0
A 10 10 5 5
A 12 7 5 2
B 8 4 4 0
B 10 3 4 -1
B 15 9 4 5
Run Code Online (Sandbox Code Playgroud)
有人能告诉我怎么做这个吗?我可以用
ddply(df, .(indv), function(x)x[which.min(x$time), ])
Run Code Online (Sandbox Code Playgroud)
得到一张像这样的桌子
indv time val
A 6 5
B 8 4
Run Code Online (Sandbox Code Playgroud)
但是,我无法弄清楚如何制作一个列val_1,其中每个人的最小值匹配.但是,如果我可以这样做,我应该可以val_change使用以下内容添加列:
df['val_change'] = df['val_1'] - df['val']
Run Code Online (Sandbox Code Playgroud)
编辑:下面发布了两个优秀的方法,但两者都依赖于我的时间列进行排序,以便小时间值在高时间值之上.我不确定我的数据总是如此.(我知道我可以先在Excel中排序,但我试图避免这种情况.)当表格显示如下时,我怎么能处理一个案例:
indv time value
A 10 10
A 6 5
A 12 7
B 8 4
B 10 3
B 15 9
Run Code Online (Sandbox Code Playgroud)
这是一个data.table内存高效的解决方案,因为它在data.table中通过引用进行设置.设置密钥将按关键变量排序
library(data.table)
DT <- data.table(df)
# set key to sort by indv then time
setkey(DT, indv, time)
DT[, c('val1','change') := list(val[1], val - val[1]),by = indv]
# And to show it works....
DT
## indv time val val1 change
## 1: A 6 5 5 0
## 2: A 10 10 5 5
## 3: A 12 7 5 2
## 4: B 8 4 4 0
## 5: B 10 3 4 -1
## 6: B 15 9 4 5
Run Code Online (Sandbox Code Playgroud)
这是一个 plyr 解决方案,使用ddply
ddply(df, .(indv), transform,
val_1 = val[1],
change = (val - val[1]))
indv time val val_1 change
1 A 6 5 5 0
2 A 10 10 5 5
3 A 12 7 5 2
4 B 8 4 4 0
5 B 10 3 4 -1
6 B 15 9 4 5
Run Code Online (Sandbox Code Playgroud)
要获得第二张桌子,请尝试以下操作:
ddply(df, .(indv), function(x) x[which.min(x$time), ])
indv time val
1 A 6 5
2 B 8 4
Run Code Online (Sandbox Code Playgroud)
要处理未排序的数据,例如您在编辑中发布的数据,请尝试以下操作
unsort <- read.table(text="indv time value
A 10 10
A 6 5
A 12 7
B 8 4
B 10 3
B 15 9", header=T)
do.call(rbind, lapply(split(unsort, unsort$indv),
function(x) x[order(x$time), ]))
indv time value
A.2 A 6 5
A.1 A 10 10
A.3 A 12 7
B.4 B 8 4
B.5 B 10 3
B.6 B 15 9
Run Code Online (Sandbox Code Playgroud)
现在您可以将上述过程应用于此排序的数据框
对数据帧进行排序的一种更短的方法是使用sortBydoBy 包中的函数
library(doBy)
orderBy(~ indv + time, unsort)
indv time value
2 A 6 5
1 A 10 10
3 A 12 7
4 B 8 4
5 B 10 3
6 B 15 9
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用对 df 进行排序ddply
ddply(unsort, .(indv, time), sort)
value time indv
1 5 6 A
2 10 10 A
3 7 12 A
4 4 8 B
5 3 10 B
6 9 15 B
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2040 次 |
| 最近记录: |