R 如何将包含第n个列表元素名称的列添加到列表的每个第n个元素?

R 如何将包含第n个列表元素名称的列添加到列表的每个第n个元素?,r,dplyr,R,Dplyr,说我有 library(dplyr) a <- list(a=tbl_df(cars), b=tbl_df(iris)) 在所有这些评论之后,我想我会写一个答案 为此,您应该使用for循环:它可以快速编码、快速执行、可读且简单明了: for (i in seq_along(a)) a[[i]]$name = names(a)[i] 您可以使用map或mappy或lappy代替for循环。在这种情况下,我认为它的可读性会降低 您还可以使用mutate而不是[来添加列。这将更慢: libr

说我有

library(dplyr)
a <- list(a=tbl_df(cars), b=tbl_df(iris))

在所有这些评论之后,我想我会写一个答案

为此,您应该使用
for
循环:它可以快速编码、快速执行、可读且简单明了:

for (i in seq_along(a)) a[[i]]$name = names(a)[i]
您可以使用
map
mappy
lappy
代替for循环。在这种情况下,我认为它的可读性会降低

您还可以使用
mutate
而不是
[
来添加列。这将更慢:

library(microbenchmark)
library(dplyr)
cars_tbl = tbl_df(cars)
mbm = microbenchmark
mbm(
    mutate = {cars_tbl = mutate(cars_tbl, name = 'a')},
    base = {cars_tbl['name'] = 'a'}
)
# Unit: microseconds
#    expr     min       lq      mean  median       uq     max neval cld
#  mutate 240.617 262.4730 293.29001 276.158 299.7255 813.078   100   b
#    base  34.971  42.1935  55.46356  53.407  57.3980 226.932   100  a 

对于这样一个简单的操作,
[在所有这些评论之后,我想我会写一个答案

为此,您应该使用
for
循环:它可以快速编码、快速执行、可读且简单明了:

for (i in seq_along(a)) a[[i]]$name = names(a)[i]
您可以使用
map
mappy
lappy
而不是for循环。在这种情况下,我认为它的可读性会降低

您还可以使用
mutate
而不是
[
来添加列。这将更慢:

library(microbenchmark)
library(dplyr)
cars_tbl = tbl_df(cars)
mbm = microbenchmark
mbm(
    mutate = {cars_tbl = mutate(cars_tbl, name = 'a')},
    base = {cars_tbl['name'] = 'a'}
)
# Unit: microseconds
#    expr     min       lq      mean  median       uq     max neval cld
#  mutate 240.617 262.4730 293.29001 276.158 299.7255 813.078   100   b
#    base  34.971  42.1935  55.46356  53.407  57.3980 226.932   100  a 


对于这样一个简单的操作,
[请提供一个可复制的数据集。在您问题的第一个代码部分,添加行
data(cars)
。在
For
循环中超级快速:
For(i In seq__-on(a))a[[i]]$name=names(a)[i]
@imo
data(cars)
是不必要的。
数据集
包多年来一直延迟加载数据(大多数其他R包也是如此)当您在一个数据帧内按大量组进行操作时,
dplyr
性能会大放异彩。您没有数据帧,而是有一个数据帧列表。
dplyr
不适用于列表,因此您需要使用
map
lappy
或其他方法对每个数据帧进行操作,并对自定义的这是一个非常简单的函数。它可能不会更快,因为你所做的很简单。请提供一个可复制的数据集。在你问题的第一个代码部分,添加行
数据(cars)
。在
for
循环中超级快速:
for(i在seq_(a)中)a[[i]]$name=names(a)[i]
@imo
数据(cars)
是不必要的。
数据集
包多年来一直延迟加载数据(大多数其他R包也是如此)当您在一个数据帧内按大量组进行操作时,
dplyr
性能会大放异彩。您没有数据帧,而是有一个数据帧列表。
dplyr
不适用于列表,因此您需要使用
map
lappy
或其他方法对每个数据帧进行操作,并对自定义的这是一个非常简单的函数。它可能不会更快,因为你所做的很简单。谢谢。如果你从两个tbl_df()开始,你的答案仍然是正确的对象,但dplyr的速度是您示例中的两倍。我只是指出这一点,因为您提到了使用
data.table
之前的转换。谢谢,这是一个很好的观点。我使用
tbl_df
对象重新运行基准测试。我无法想象有人会多次执行此操作,因此microsecond基准测试在很大程度上让我觉得毫无意义。增加输入数据的大小,使一次运行需要人类可测量的时间,这更有趣。我强烈同意。除了OP在我第一次提出一个简单循环后的评论外,我根本不会进行基准测试:“我在考虑在每个tbl_df上调用一个mutate,最好使用一个函数而不是一个循环(这不是更快吗?。。。“我可能应该强调的是,区别是微不足道的。@Dambo任何向量化解决方案,在其核心,仍然只是一个简单的循环。区别在于,通常对于向量化解决方案,循环发生在编译的内部代码中,而不是在解释器中执行显式循环(这涉及到对循环的每个步骤进行多层次的语法、解释等)。显然,这种差异主要对大型循环有影响,例如,在大型
数据.frame
的行上循环。在这种情况下—(a)没有内部循环可以完成这项工作,(b)循环可能很小(=列表中的表格数)。谢谢。如果从两个tbl_df()开始,您的答案仍然正确对象,但dplyr的速度是您示例中的两倍。我只是指出这一点,因为您提到了使用
data.table
之前的转换。谢谢,这是一个很好的观点。我使用
tbl_df
对象重新运行基准测试。我无法想象有人会多次执行此操作,因此microsecond基准测试在很大程度上让我觉得毫无意义。增加输入数据的大小,使一次运行需要人类可测量的时间,这更有趣。我强烈同意。除了OP在我第一次提出一个简单循环后的评论外,我根本不会进行基准测试:“我在考虑在每个tbl_df上调用一个mutate,最好使用一个函数而不是一个循环(这不是更快吗?。。。“我可能应该强调的是,区别是微不足道的。@Dambo任何向量化解决方案,在其核心,仍然只是一个简单的循环。区别在于,通常对于向量化解决方案,循环发生在编译的内部代码中,而不是在解释器中执行显式循环(这涉及到对循环的每个步骤进行多层次的语法、解释等)。显然,这种差异主要对大型循环有影响,例如,在大型
数据.frame
的行上循环。在这种情况下—(a)没有内部循环可以完成这项工作,(b)循环可能很小(=列表中的表数)。
# base for loop
for (i in seq_along(a)) {
    a[[i]]$name = names(a)[i]
}

# dplyr in for loop
for (i in seq_along(a)) {
    a[[i]] = mutate(a[[i]], name = names(a)[i])
}

# dplyr hiding the loop in Map()
a = Map(function(x, y) mutate(x, name = y), x = a, y = names(a))