在R中的列表上使用apply族和多个函数

在R中的列表上使用apply族和多个函数,r,vectorization,R,Vectorization,在回答这个问题之后,我有一个问题 我的解决方案是使用for循环,但我们应该尽可能地进行优化(矢量化) 我想了解的是我将如何将我在文章中提出的解决方案矢量化 我的解决办法是 for(i in 1:length(graph_list)){ graph_list[[i]]=set_vertex_attr(graph_list[[i]],"gender", value=attribute_df$gender[match(V(graph_list[[i]])$name, attribute_df$n

在回答这个问题之后,我有一个问题

我的解决方案是使用for循环,但我们应该尽可能地进行优化(矢量化)

我想了解的是我将如何将我在文章中提出的解决方案矢量化

我的解决办法是

for(i in 1:length(graph_list)){
  graph_list[[i]]=set_vertex_attr(graph_list[[i]],"gender", value=attribute_df$gender[match(V(graph_list[[i]])$name, attribute_df$names)])
}
理想情况下,我们可以使用
lappy
将其矢量化,但我在构思如何实现这一点时遇到了一些困难。这是我得到的

graph_lists_new=lapply(graph_list, set_vertex_attr, value=attribute_df$gender[match(V(??????????)$name, attribute_df$names)]))
我不清楚的是我在
??
部分中放了什么。
V()
函数中的内容应该是列表中的每一项,但我没有得到的是我在使用
lappy
时放入的内容

所有的数据都可以在我发布的链接中找到,但这里还是有数据

attribute_df<- structure(list(names = structure(c(6L, 7L, 5L, 2L, 1L, 8L, 3L, 
4L), .Label = c("Andy", "Angela", "Eric", "Jamie", "Jeff", "Jim", 
"Pam", "Tim"), class = "factor"), gender = structure(c(3L, 2L, 
3L, 2L, 3L, 1L, 1L, 2L), .Label = c("", "F", "M"), class = "factor"), 
    happiness = c(8, 9, 4.5, 5.7, 5, 6, 7, 8)), class = "data.frame", row.names = c(NA, 
-8L))



edgelist<-list(structure(list(nominator1 = structure(c(3L, 4L, 1L, 2L), .Label = c("Angela", 
"Jeff", "Jim", "Pam"), class = "factor"), nominee1 = structure(c(1L, 
2L, 3L, 2L), .Label = c("Andy", "Angela", "Jeff"), class = "factor")), class = "data.frame", row.names = c(NA, 
-4L)), structure(list(nominator2 = structure(c(4L, 1L, 2L, 3L
), .Label = c("Eric", "Jamie", "Oscar", "Tim"), class = "factor"), 
    nominee2 = structure(c(1L, 3L, 2L, 3L), .Label = c("Eric", 
    "Oscar", "Tim"), class = "factor")), class = "data.frame", row.names = c(NA, 
-4L)))

graph_list<- lapply(edgelist, graph_from_data_frame)

attribute\u df由于您需要在调用中多次使用
graph\u list[[i]]
,要使用
lappy
您需要编写一个自定义函数,例如此匿名函数。(它的代码与您的循环相同,我只是将其包装在
函数(x)
中,并将
graph\u list[[I]]
的所有实例替换为
x

(请注意,我没有测试这个,但它应该可以工作,除非我打错了。)


lappy
不是矢量化——它只是“循环隐藏”。在这种情况下,我认为您的
for
循环比
lappy
更好。特别是由于您正在修改现有对象,因此简单的
for
循环可能比
lappy
解决方案更有效,也更具可读性

当我们谈论效率的向量化时,我们几乎总是指原子向量,而不是
list
s。(毕竟,这是矢量化,而不是列表化。)使用
lappy
和相关函数(
sappy
vappy
Map
,大多数
purr
包)的原因不是计算机效率,而是可读性和人类写作效率

假设您有一个数据帧列表,
my_list=list(iris、mtcars、CO2)
。如果要获取列表中每个数据帧的行数并将其存储在变量中,我们可以使用
sapply
for
循环:

# easy to write, easy to read
rows_apply = sapply(my_list, nrow)

# annoying to read and write
rows_for = integer(length(my_list))
for (i in seq_along(my_list)) rows_for[i] = nrow(my_list[[i]])
但是任务越复杂,
for
循环的可读性就越强。在您的情况下,我更喜欢
for
循环


有关这方面的更多阅读,请参阅旧问题。自从编写了这些答案之后,R已经升级到包含一个即时编译器,它进一步加快了与应用相关的
循环的
。在这些近10年的答案中,您会看到有时
*apply
for
循环稍快。由于使用了JIT编译器,我认为您会发现相反的情况:大多数情况下,
for
循环比
*apply
稍快


但在这两种情况下,除非您在for/apply中做了一些非常琐碎的事情,您在for/apply中所做的任何事情都将主导计时

因为您需要在调用中多次使用
图表列表[[i]]
,要使用
lappy
您需要编写一个自定义函数,比如这个匿名函数。(它的代码与您的循环相同,我只是将其包装在
函数(x)
中,并将
graph\u list[[I]]
的所有实例替换为
x

(请注意,我没有测试这个,但它应该可以工作,除非我打错了。)


lappy
不是矢量化——它只是“循环隐藏”。在这种情况下,我认为您的
for
循环比
lappy
更好。特别是由于您正在修改现有对象,因此简单的
for
循环可能比
lappy
解决方案更有效,也更具可读性

当我们谈论效率的向量化时,我们几乎总是指原子向量,而不是
list
s。(毕竟,这是矢量化,而不是列表化。)使用
lappy
和相关函数(
sappy
vappy
Map
,大多数
purr
包)的原因不是计算机效率,而是可读性和人类写作效率

假设您有一个数据帧列表,
my_list=list(iris、mtcars、CO2)
。如果要获取列表中每个数据帧的行数并将其存储在变量中,我们可以使用
sapply
for
循环:

# easy to write, easy to read
rows_apply = sapply(my_list, nrow)

# annoying to read and write
rows_for = integer(length(my_list))
for (i in seq_along(my_list)) rows_for[i] = nrow(my_list[[i]])
但是任务越复杂,
for
循环的可读性就越强。在您的情况下,我更喜欢
for
循环


有关这方面的更多阅读,请参阅旧问题。自从编写了这些答案之后,R已经升级到包含一个即时编译器,它进一步加快了与应用相关的
循环的
。在这些近10年的答案中,您会看到有时
*apply
for
循环稍快。由于使用了JIT编译器,我认为您会发现相反的情况:大多数情况下,
for
循环比
*apply
稍快


但在这两种情况下,除非您在for/apply中做了一些非常琐碎的事情,您在for/apply中所做的任何事情都将主导计时

lappy
不是矢量化,而是“循环隐藏”。在这种情况下,您的
for
循环比
lappy
更好。由于您正在修改现有对象,而
lappy
可能需要制作一个完整的副本,因此您的简单
for
循环几乎肯定会比
lappy
解决方案更有效,并且更具可读性。
lappy
不是矢量化,它只是“循环隐藏”。在这个