我正在尝试使用rbind合并许多数据帧。如果我直接打电话给rbind,那就没问题了:
> test <- rbind(x)
> is.data.frame(x)
[1] TRUE
但是,如果我使用do.call
,我会遇到一个问题,即我的字符列已折叠,数据框将转换为矩阵。
>test <- do.call("rbind", x)
> is.data.frame(test)
[1] FALSE
根据?rbind文档我试过add stringsAsFactors = FALSE
但行为没有变化。我的数据表看起来像这样:
ID sequence descriptor
1 aaacccttt g12
2 actttgtgt e34
3 tttgggctc b12
4 ccgcgcgcg c12
… … ...
并且rbind输出如下所示,但do.call("rbind", x)
输出如下所示,其中sequence列不再是字符:
ID 363 426 91
Sequence 98 353 100
descriptor g12 b12 c12
我想使用do.call,因为我循环使用一组数据帧,以便使用下面的脚本合并它们。另一个有用的答案可能提供一个替代解决方案,如何在循环中调用多个数据帧时合并它们。
stringsAsFactors = FALSE
dfs <- as.list(ls(pattern="Data_"))
for (i in 1:length(dfs)) {
x <- get(as.character(dfs[i]))
AllData <- do.call("rbind", x)
}
dfs
是我工作环境中的数据框列表,我使用get
获取实际数据框
答案 0 :(得分:4)
有两个不同的问题会给你带来困难。
stringsAsFactors
你是正确的看stringsAsFactors
,但是没有把它称为正确的地方。
您有两种选择。您可以在options
中设置它,如下所示:
options(stringsAsFactors=FALSE)
或者在用于创建data.table
s:
a <- read.table(textConnection("ID sequence descriptor
1 aaacccttt g12
2 actttgtgt e34
3 tttgggctc b12
4 ccgcgcgcg c12"),
header=T, stringsAsFactors=FALSE)
args=
do.call()
您也希望使用do.call()
来实现这一目标。但是,正如@Sacha指出的那样,dfs
需要是data.frame
的列表,而不是单个data.frame
(它本身就是向量列表)。
# Create list of two data.frames
b <- a
dfs <- list(a, b)
# Or, if you start with a list of their names
dfs <- list("a", "b")
dfs <- lapply(dfs, get)
# Check that this works
do.call("rbind", dfs)
# ID sequence descriptor
# 1 1 aaacccttt g12
# 2 2 actttgtgt e34
# 3 3 tttgggctc b12
# 4 4 ccgcgcgcg c12
# 5 1 aaacccttt g12
# 6 2 actttgtgt e34
# 7 3 tttgggctc b12
# 8 4 ccgcgcgcg c12
即使您只有一个data.frame
,这也适用于您,只要它包含在(length-1)list
中,就像这样:dfs <- list(a)
< / p>
答案 1 :(得分:2)
使用Josh&#39;示例代码。我很确定发生的事情是这样的:
Data:
x <- read.table(textConnection("ID sequence descriptor
1 aaacccttt g12
2 actttgtgt e34
3 tttgggctc b12
4 ccgcgcgcg c12"),
header=T, stringsAsFactors=FALSE)
首先:
rbind(x)
什么都不做,因为只有一个参数。即没有任何东西可以附加到数据框,因此它只返回相同的数据帧。然后:
do.call("rbind", x)
这里发生的是使用列表rbind()
中的所有参数调用x
。数据框是列为元素的列表。因此,这将与:
rbind(x$ID,x$sequence,x$descriptor)
所以你按行排列三个向量。因此,这成为你所拥有的转置,因为data.frames只存储不同类型的向量列,这必须成为一个字符矩阵。
我认为如果x
是一个数据框列表,它可以正常工作。它本身不应该是一个数据框。
答案 2 :(得分:1)
我认为你所寻求的可以在没有使用Reduce
的循环的情况下完成。它是一个高阶函数,它将函数连续应用于列表中的两个元素。
dfs <- as.list(ls(pattern="Data_"))
Reduce('rbind', dfs)