我有一个有点复杂的数据结构,看起来像这样:
x <- list(
list(1, "a", 2, "b", 0.1),
list(3, "c", 4, "d", 0.2),
list(5, "e", 6, "f", 0.3)
)
y <- rep(list(x), 10)
我有一个数据框,
df <- data.frame(
x1 = c(0.33,1.67,-0.62,-0.56,0.17,0.73,0.59,0.56,-0.22,1.49),
x2 = c(-0.82,1.22,0.65,0.54,-2.26,1.21,-0.44,-0.92,-0.56,0.50),
x3 = c(-0.16,0.49,-0.82,-0.71,0.13,1.22,1.23,-0.01,-1.11,0.97)
)
(the列名不重要),并且基本上 Dataframe 的每一行(即,0.33、-0.82和-0.16)表示需要在y
内的x
的每个副本的每个子列表的最后位置中的值。
我的python/julia大脑在循环中工作得最好,所以我可以通过循环y,然后循环每个sub-sub列表来得到我想要的结果,如下所示:
for(i in seq_len(length(y))) {
for(j in 1:3) {
y[[i]][[j]][[5]] <- df[[i, j]]
}
}
这是可行的。但是对于我拥有的大得多的数据来说,它真的很慢。所以我试着找出最快的矢量化版本。
我一直在尝试使用Map()
,但肯定是搞砸了某处,错过了一个步骤,因为这:
y_new <- y
for (j in 1:3) {
y_new <- Map(function(sublist, value) {sublist[[5]] <- value; sublist},
y_new, df[, j])
}
不起作用(identical(y, y_new)
返回FALSE
,我想我在这里遗漏了一个子集级别。
我根本没有嫁给Map()
,从字面上看,我正在寻找的只是嵌套for循环的 * 最快 * 替代品。
任何/所有的帮助都非常感谢!!
3条答案
按热度按时间kiz8lqtg1#
使用
Map
,我们可以作为一种矢量化方法,可以选择
unlist
并指定suzh9iv82#
我们可以使用
map2
两次:首先,我们使用
asplit(df, 1)
将 Dataframedf
转换为一个向量列表,第一个map2()
迭代y
和行向量列表,第二个map2()
将y
中每个嵌套列表的第5个元素替换为df中的相应值。我们使用大括号
{}
和分号;
将多个表达式组合为单个表达式。9jyewag03#
@akrun关于取消列表和重新列表的建议很优雅,也很符合习惯用法(“R式”)。
但我希望这样做时不要强制,特别是从数字到字符再到字符,这可能会很慢,并导致精度损失。像这样的操作会更快更安全:
这里有一个基准:
x一个一个一个一个x一个一个二个x
请注意,只有第三和第四个答案与第一个答案相同(在
identical
的意义上)。第二个答案由于精度损失而不同。