改进嵌套速度,以创建邻接矩阵的循环速度

问题描述 投票:1回答:1

我想创建一个邻接矩阵。矩阵应显示每个关键字有多少个相同的值字符串。

我目前使用的两个for循环方法在处理更多数据时会花费一些时间。我已经研究过foreach包,但无法理解本示例。我将不胜感激您对任何速度提升的帮助;)

#create reproducible dataset
set.seed(11)
x <- rep('keyword', 10)
y <- seq(1, 10)
z <- rep('value', 10)

df <- tibble::tibble(Keyword = rep(paste0(x,y),4), 
                     Values = paste0(sample(z, 40, replace = TRUE), 
                                     sample(y, 40, replace = TRUE)))

#format dataset
temp_df <- df %>% 
  dplyr::group_by(Keyword) %>%
  dplyr::summarise(Values = toString(Values))  %>%
  dplyr::ungroup() %>%
  dplyr::distinct(Keyword, .keep_all = TRUE)

#initialise adjacency matrix
adj_matrix <- data.frame()

#for loops to iterate through values
for (i in 1:nrow(temp_df)) {

  y <- trimws(unlist(strsplit(temp_df$Values[i], split = ',')))

  for (g in i:nrow(temp_df)) {

    f <- trimws(unlist(strsplit(temp_df$Values[0+g], split = ',')))
    z <- y %in% f
    adj_matrix[i,g] <- sum(z)

  }
}

#name rows and columns
colnames(adj_matrix) <- temp_df$Keyword
rownames(adj_matrix) <- temp_df$Keyword

adj_matrix是稀疏的(即仅填充了其中一半),您可以看到哪个关键字共享了多少个相同的Value字符串。有了这个矩阵,我可以轻松地在网络图中显示关系。

提前感谢!

Jan

r foreach dplyr adjacency-matrix doparallel
1个回答
1
投票

我不清楚您的实际数据是以df还是temp_df开头。无论哪种方式,都可以通过使用outer()来避免嵌套循环中的处理,这可以使处理速度有所提高。

library(dplyr)
library(purrr)

am_outer <- df %>%
  split(f = .$Keyword) %>%
  map(pull, Values) %>%
  outer(., ., function(x,y) sapply(seq_along(x), function(i) sum(x[[i]] %in% y[[i]])))

am_outer[lower.tri(am_outer)] <- NA

identical(data.frame(am_outer), adj_matrix)

[1] TRUE

如果数据以temp_df开头,则可以使用:

temp_df %>% 
  separate_rows(Values, sep = ", ") %>% 
  split(f = .$Keyword) %>%
  map(pull, Values) %>%
  outer(., ., function(x,y) sapply(seq_along(x), function(i) sum(x[[i]] %in% y[[i]])))
© www.soinside.com 2019 - 2024. All rights reserved.