2016-01-19 137 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

相关问题