使用data.table包(该包具有 reshape2 的 melt
和 dcast
函数的改进实现),您可以按照以下方式执行此操作:
newdf <- dcast(setDT(df)[, idx := 1:.N, by = id], id ~ paste0("bp",idx), value.var = "bp")
或者利用新的 rowid
函数:
newdf <- dcast(setDT(df), id ~ rowid(prefix="bp",id), value.var = "bp")
两个选项给出相同的结果:
> newdf
id bp1 bp2 bp3
1: 1 120 134 129
2: 2 110 124 119
但正如@SamDickson所说,当你想计算(例如)前两个血压测量的平均值时,你也可以向现有数据框df
添加一个新变量:
df$first2mn <- ave(df$bp, df$id, FUN = function(x) mean(x[1:2]))
setDT(df)[, first2mn := mean(bp[1:2]), id]
两者都给出:
> df
id date bp first2mn
1: 1 21/1/14 120 127
2: 1 19/3/14 134 127
3: 1 3/5/14 129 127
4: 2 21/1/14 110 117
5: 2 19/3/14 124 117
6: 2 3/5/14 119 117
或者只需使用以下方法计算平均值:
aggregate(bp ~ id, df, function(x) mean(x[1:2]))
setDT(df)[, .(bp = mean(bp[1:2])), id]
两者都给出:
id bp
1 1 127
2 2 117
使用的数据:
df <- read.table(text="id date bp
1 21/1/14 120
1 19/3/14 134
1 3/5/14 129
2 21/1/14 110
2 19/3/14 124
2 3/5/14 119", header=TRUE)
ave/dcast
的使用很好。加一。 - akrun[.data.frame
(df, df$bp.id %in% paste0("BP", 1:3)) : undefined columns selected。有什么想法吗?每个id都有超过3个bp观察值(最大为14),当我将1:3更改为1:14时,仍然会出现相同的错误。 - Jamesdf2 <- dcast(df, id~bp.id, value.var="bp")
。如果这不起作用,请尝试这个df2 <- dcast(df[df$bp.id %in% paste0("BP",1:3),], id~bp.id, value.var="bp")
或这个df2 <- dcast(df[grep("BP",df$bp.id),], id~bp.id, value.var="bp")
。 - Sam Dickson