我在R中有一个数据帧列表。列表中的所有数据帧都具有相同的大小。但是,元素可以是不同类型的。例如,
我想将一个函数应用于数据框的相应元素。例如,我想使用粘贴功能来生成数据框,例如
"1a" "2b" "3c"
"4d" "5e" "6f"
在R中是否有直接的方法。我知道可以使用Reduce函数在列表中的数据帧的相应元素上应用函数。但在这种情况下使用Reduce功能似乎没有达到预期的效果。
Reduce(paste,l)
产地:
"c(1, 4) c(\"a\", \"d\")" "c(2, 5) c(\"b\", \"e\")" "c(3, 6) c(\"c\", \"f\")"
想知道我是否可以在不写乱码for循环的情况下做到这一点。任何帮助表示赞赏!
答案 0 :(得分:6)
而不是Reduce
,请使用Map
。
# not quite the same as your data
l <- list(data.frame(matrix(1:6,ncol=3)),
data.frame(matrix(letters[1:6],ncol=3), stringsAsFactors=FALSE))
# this returns a list
LL <- do.call(Map, c(list(f=paste0),l))
#
as.data.frame(LL)
# X1 X2 X3
# 1 1a 3c 5e
# 2 2b 4d 6f
答案 1 :(得分:3)
要更多地解释@ mnel的优秀答案,请考虑将两个向量的相应元素相加的简单示例:
Map(sum,1:3,4:6)
[[1]]
[1] 5 # sum(1,4)
[[2]]
[1] 7 # sum(2,5)
[[3]]
[1] 9 # sum(3,6)
Map(sum,list(1:3,4:6))
[[1]]
[1] 6 # sum(1:3)
[[2]]
[1] 15 # sum(4:6)
为什么第二个案例可能会通过添加第二个列表变得更加明显,例如:
Map(sum,list(1:3,4:6),list(0,0))
[[1]]
[1] 6 # sum(1:3,0)
[[2]]
[1] 15 # sum(4:6,0)
现在,下一个更棘手。正如帮助页面?do.call
所述:
‘do.call’ constructs and executes a function call from a name or a
function and a list of arguments to be passed to it.
所以,做:
do.call(Map,c(sum,list(1:3,4:6)))
使用列表Map
的输入调用c(sum,list(1:3,4:6))
,如下所示:
[[1]] # first argument to Map
function (..., na.rm = FALSE) .Primitive("sum") # the 'sum' function
[[2]] # second argument to Map
[1] 1 2 3
[[3]] # third argument to Map
[1] 4 5 6
......因此相当于:
Map(sum, 1:3, 4:6)
看起来很熟悉!它等同于本答案顶部的第一个例子。