2016-01-19 132 views
1

我讓自己都束縛在試圖理解下面的代碼發生了什麼事情。我試圖爲data.frame中的每一行創建一個向量,然後附加到原始的。我期望下面的代碼返回一個數組列表。它似乎返回列表的列表,內部列表包含數組?我怎麼能得到我想要的 - 一個新的列附加每個元素是一個數組?爲什麼foreach返回一個列表

df <- mtcars 

library(foreach) 
library(iterators) 

df$x = foreach (row = iter(df, by='row')) %do% { 
    profile <- as.numeric(row[,c('mpg', 'cyl', 'disp')]) 
    return(profile) 
} 

我期待的結果:

df[1,]$x == as.numeric(df[1,c('mpg', 'cyl', 'disp')]) 

,而不是我得到

df[1,]$x[1] == as.numeric(df[1,c('mpg', 'cyl', 'disp')]) 

(這裏我用==來表示兩個集合都是一樣的,我意識到[R大概不會以這種方式實現列表相等運算符)

+0

我不確定你想要得到的輸出。你期望從'df [1,] $ x [1]'得到什麼? –

+0

我試圖讓df [1,] $ x返回df [1,] $ x [1]所做的 - 即as.numeric(row [1,c('mpg','cyl','disp ')]) – user2981639

+0

如果你執行'str(df)',你會看到'df $ x'是一個向量列表,這是你的例子中foreach的返回值。如果您將組合函數更改爲'rbind',那麼'df $ x'將是一個矩陣。 –

回答

1

foreach包默認返回你輸入的列表的列表(一個列表,每次迭代)。這就是爲什麼你最終會輸出錯誤的結果。你可以在foreach循環中使用.combine選項來改變它。如果我理解正確,你希望逐行追加。這可以通過指定.combine = 'rbind'來實現,它使用熟悉的rbind函數來組合每個循環迭代的輸出。如果訂單不相關,則還應指定.inorder = FALSE以加速代碼。 (TRUE是默認設置,所以如果訂單是相關的,則不需要打擾。) 因此請嘗試使用foreach (row = iter(df, by='row'), .combine='rbind') %do% ...來代替它,看看它是否能完成這項工作。

+0

謝謝,這個cbind不起作用,但rbind似乎。如果我使用rbind,那麼我認爲結果是一個數組 - 即以下函數df [1,] $ x * df [1,] $ x(即產生一個元素明智的乘法)。我很困惑,因爲我不是100%確定在Rstudio中如何檢查結果是什麼類型,即typeof(df [1,] $ x)表示「double」 – user2981639

+0

哦,謝謝指出,我想我必須擁有意思是'rbind',因爲'cbind'對你的問題沒有任何意義 - 我編輯了答案。很高興我能幫忙! :) –

1

此問題不是由造成的3210。因爲您想要將矢量分配給數據框的單元格(或元素)而不是數據框的列。 foreach函數必須強制該向量爲list

例如。

df1 <- data.frame(x1=1:4, x2=letters[1:4], stringsAsFactors = FALSE) 
df1$x1[1] <- 5:8 
# Warning message: 
# In df1$x1[1] <- 5:8 : 
# number of items to replace is not a multiple of replacement length 
df1 
# x1 x2 
# 1 5 a 
# 2 2 b 
# 3 3 c 
# 4 4 d 
df1$x1[1] <- list(5:8) 
df1 
#   x1 x2 
# 1 5, 6, 7, 8 a 
# 2   2 b 
# 3   3 c 
# 4   4 d 
df1$x1[1] 
# [[1]] 
# [1] 5 6 7 8 
df1$x1[[1]] 
# [1] 5 6 7 8 

其實,你應該使用[[而不是[

df[1, ]$x[[1]] == as.numeric(df[1,c('mpg', 'cyl', 'disp')]) 
# [1] TRUE TRUE TRUE 

作爲list[1]仍然是一個列表,同時list[[1]]提取的list第一個元素。看下面的例子。

lst1 <- list(x1=1:4, x2=letters[1:5]) 
lst1[1] 
# $x1 
# [1] 1 2 3 4 
lst1[[1]] 
# [1] 1 2 3 4 

另外,你可以使用:的

df$x[[1]] 
[1] 21 6 160 

代替:

df[1, ]$x[[1]] 
# [1] 21 6 160 
+0

這不是問題。 –

+0

查看我的更新。@Pascal –

+0

謝謝,但@Pascal說我明白如何訪問結果,問題是爲什麼是foreach返回列表的列表,我如何使它返回一個列表 – user2981639

相關問題