我在R中有多个具有完全相同结构的数据帧,我想在一个数据帧中垂直合并它们。 unsplit()
似乎是一项正确的功能。但是,我无法使其发挥作用。
最终我将这一切都简化为这个简单的案例:
> df <- data.frame("ch" = c("A", "B"), "num" = c(1, 2));
> df
ch num
1 A 1
2 B 2
> divided <- split(df, df$ch);
> divided
$A
ch num
1 A 1
$B
ch num
2 B 2
> changed <- lapply(divided, function (x) {data.frame("ch" = x$ch, "num" = x$num + 1)})
> changed
$A
ch num
1 A 2
$B
ch num
1 B 3
> unsplit(changed, df$ch)
Error in `row.names<-.data.frame`(`*tmp*`, value = value) :
duplicate 'row.names' are not allowed
In addition: Warning message:
non-unique value when setting 'row.names': ‘1’
所以问题是 - 为什么unsplit()
在这种情况下不起作用?什么是使用该功能的正确方法?
P.S。我可以使用do.call('rbind', changed)
来解决我的任务,但这个问题是关于unsplit()
的正确用法。
答案 0 :(得分:1)
您需要手动覆盖rownames以避免“重复的rownames”错误,例如:
changed <- lapply(divided, function (x) {
temp <- data.frame("ch" = x$ch, "num" = x$num + 1)
row.names(temp) <-
paste(x$ch, 1:nrow(x), sep = ".")
return(temp)
})
unsplit(changed, df$ch)
顺便说一句,请bind_rows
dplyr
查看do.call
作为使用unsplit
的替代方法,这可能会让您更愿意离开{{1}}
答案 1 :(得分:1)
1)分割后,递增num
而不从头开始重构组件数据框,如下所示:
L <- lapply(divided, transform, num = num+1)
然后unsplit
将起作用:
> unsplit(L, df$ch)
ch num
1 A 2
2 B 3
2)如果必须从头开始重建数据框,但要保持每个组件中的行数相同,则使用原始行名称。除了我们添加了row.names=
之外,这是您的代码。现在它起作用了:
changed2 <- lapply(divided,
function (x) data.frame(ch = x$ch, num = x$num + 1, row.names = rownames(x)))
unsplit(changed2, df$ch)
3)如果要重建数据框以便有更多行,那么您需要合成新的唯一行名称,例如,在@Mark Peterson的解决方案中