我有这种格式的大型data.frame(20000+条目):
id D1 D2
1 0.40 0.21
1 0.00 0.00
1 0.53 0.20
2 0.17 0.17
2 0.25 0.25
2 0.55 0.43
每个id可以重复3-20次。我想将重复的行合并到新列中,因此我的新data.frame看起来像:
id D1 D2 D3 D4 D5 D6
1 0.40 0.21 0.00 0.00 0.53 0.20
2 0.17 0.17 0.25 0.25 0.55 0.43
我之前使用plyr操作过data.frames,但我不知道如何处理这个问题。任何帮助将不胜感激。谢谢。
答案 0 :(得分:4)
最好的选择是从“reshape2”中使用melt
和dcast
。但在我们跳到那个选项之前,让我们看看我们还有什么可用的东西:
您提到每个“id”的行数不平衡。这将使得整齐的矩形data.frame
变得有些困难。
以下是一些例子。
mydf <- structure(list(id = c(1, 1, 1, 2, 2, 2),
D1 = c(0.4, 0, 0.53, 0.17, 0.25, 0.55),
D2 = c(0.21, 0, 0.2, 0.17, 0.25, 0.43)),
.Names = c("id", "D1", "D2"), row.names = c(NA, 6L),
class = "data.frame")
mydf
# id D1 D2
# 1 1 0.40 0.21
# 2 1 0.00 0.00
# 3 1 0.53 0.20
# 4 2 0.17 0.17
# 5 2 0.25 0.25
# 6 2 0.55 0.43
使用此类数据,您只需使用aggregate
:
do.call(data.frame, aggregate(. ~ id, mydf, as.vector))
# id D1.1 D1.2 D1.3 D2.1 D2.2 D2.3
# 1 1 0.40 0.00 0.53 0.21 0.00 0.20
# 2 2 0.17 0.25 0.55 0.17 0.25 0.43
如果您为“id = 2”添加了第四个值,aggregate
将无效:
mydf[7, ] <- c(2, .44, .33)
do.call(data.frame, aggregate(. ~ id, mydf, as.vector))
# Error in data.frame(`0` = c(0.4, 0, 0.53), `1` = c(0.17, 0.25, 0.55, 0.44 :
# arguments imply differing number of rows: 3, 4
最好只生成list
的{{1}}:
vector
或者,如果您坚持使用矩形lapply(split(mydf[-1], mydf[[1]]), function(x) unlist(x, use.names=FALSE))
# $`1`
# [1] 0.40 0.00 0.53 0.21 0.00 0.20
#
# $`2`
# [1] 0.17 0.25 0.55 0.44 0.17 0.25 0.43 0.33
#
,请探索data.frame
不平衡数据的多个工具之一,例如,来自“plyr”的rbind
:
rbind.fill
或者,您可以使用“reshape2”中的library(plyr)
rbind.fill(lapply(split(mydf[-1], mydf[[1]]),
function(x) data.frame(t(unlist(x, use.names=FALSE)))))
# X1 X2 X3 X4 X5 X6 X7 X8
# 1 0.40 0.00 0.53 0.21 0.00 0.20 NA NA
# 2 0.17 0.25 0.55 0.44 0.17 0.25 0.43 0.33
和melt
,如下所示:
dcast