繁体   English   中英

在R中的列表上使用Apply系列和多项功能

[英]Using apply family and multiple functions on lists in R

在这个问题的答案后面有一个问题,在边列表R中匹配顶点属性

我的解决方案是使用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)])
}

理想情况下,我们可以使用lapply将其向量化,但是在构思如何做到这一点时遇到了一些麻烦。 这就是我所拥有的

graph_lists_new=lapply(graph_list, set_vertex_attr, value=attribute_df$gender[match(V(??????????)$name, attribute_df$names)]))

我不清楚的是我将在??????部分中放置什么? V()函数内部的东西应该是列表中的每个项目,但是我没有得到的是当我使用lapply时要放在里面的lapply

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

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)

由于您需要在调用中多次使用graph_list[[i]] ,因此要使用lapply您需要编写一个自定义函数,例如此匿名函数。 (这是相同的代码,你的循环,我只是把它包在function(x)和替换的所有实例graph_list[[i]]x )。

graph_list = lapply(graph_list, function(x)
  set_vertex_attr(x, "gender", value = attribute_df$gender[match(V(x)$name, attribute_df$names)])
)

(请注意,我没有对此进行测试,但是除非输入错误,否则它应该可以工作。)

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

当我们谈论矢量化以提高效率时,我们几乎总是指原子矢量,而不是list (毕竟,它是矢量化 ,而不是列表化 。)使用lapply和相关功能( sapplyvapplyMap ,大多数purrr软件包)的原因不是计算机效率, 可读性和人工效率。

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

# 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已经升级到包括刚刚在即时编译器,进一步加快其for相回路申请。 在近10年历史的答案在那里,你会发现有时 *applyfor循环。 从JIT编译器开始,我想您会发现相反的情况: 大多数情况下, for循环比*apply 快。

但是在这两种情况下,除非您在for / apply内部做的事情绝对微不足道 ,否则您在for / apply内部所做的任何事情都将主导时间

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM