簡體   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