我让自己陷入困境,试图了解下面的代码是怎么回事。我正在尝试为data.frame中的每一行创建一个向量,然后附加到原始行。我希望下面的代码返回一个数组列表。它似乎返回一个列表列表,内部列表包含数组?我怎么能得到我想要的东西 - 一个新的列附加每个元素是一个数组?
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 :(得分:1)
此问题不是由foreach
引起的。您希望将向量分配给数据框的单元(或元素)而不是数据框的列。 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
答案 1 :(得分:1)
默认情况下,foreach
包会返回输入列表的列表(每次迭代一个列表)。这就是为什么你最终输出“错误”的原因。您可以使用foreach循环中的.combine
选项更改此设置。如果我理解正确,你希望逐行追加。这可以通过指定.combine = 'rbind'
来实现,rbind
使用熟悉的.inorder = FALSE
函数来组合每个循环迭代的输出。如果订单无关紧要,您还应指定TRUE
以加快代码速度。 (foreach (row = iter(df, by='row'), .combine='rbind') %do% ...
是默认值,因此如果订单相关,您无需费心。)
因此,请尝试使用Line-height
,看看它是否能胜任。