2011-11-01 125 views
5

我想使用rbind合併一些數據幀。如果我叫rbind directy沒有問題:使用do.call時丟失數據幀

> test <- rbind(x) 
> is.data.frame(x) 
[1] TRUE 

但是,如果我用do.call我跑到哪裏我的性格列倒塌問題,數據幀轉換爲矩陣。

>test <- do.call("rbind", x) 
> is.data.frame(test) 
[1] FALSE 

根據文獻記錄,我嘗試了add stringsAsFactors = FALSE但行爲沒有變化。我的數據表是這個樣子:

ID sequence descriptor 
1 aaacccttt g12 
2 actttgtgt e34 
3 tttgggctc b12 
4 ccgcgcgcg c12 
… …  ... 

和rbind輸出看起來是這樣,但do.call("rbind", x)輸出顯示如下,其中序列列不再是一個性格:

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是我的工作環境dataframes的名單,我得到使用get

謝謝你實際的數據幀。

回答

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,只要它被包裹在一個(長度1)list,就像這樣:dfs <- list(a)

+0

這是一個很棒的答案。 – zach

2

使用喬希示例代碼。我敢肯定的是正在發生的事情是這樣的:

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只在columnwise存儲不同類型的向量,所以它必須成爲一個字符矩陣。

我認爲,如果x是一個數據框的列表,它工作正常。它本身不應該是一個數據框架。

+0

謝謝Sacha,我想你已經完全描述了最新情況 – zach

1

我認爲你可以在沒有使用Reduce的循環的情況下完成。它是一個高階函數,它將一個函數連續地應用於列表中的兩個元素。

dfs <- as.list(ls(pattern="Data_")) 
Reduce('rbind', dfs) 
+0

謝謝Ramnath,但是當我嘗試這種方法時,我不返回數據集,而是返回一個字符矩陣。我不知道Reduce,所以我一定會研究它。 – zach