Seb*_*Seb 7 r igraph adjacency-matrix find-occurrences dplyr
我是 R 的新手,目前正在处理边缘列表形式的协作数据,该列表具有 32 列和大约 200.000 行。我想根据国家之间的相互作用创建一个(共)现矩阵。但是,我想通过对象的总数来计算交互次数。
如果在一行中“England”出现了 3 次而“China”只出现了一次,结果应该是下面的矩阵。
England China
England 3 3
China 3 1
Run Code Online (Sandbox Code Playgroud)
df <- data.frame(ID = c(1,2,3,4),
V1 = c("England", "England", "China", "England"),
V2 = c("Greece", "England", "Greece", "England"),
V32 = c("USA", "China", "Greece", "England"))
Run Code Online (Sandbox Code Playgroud)
因此,示例数据框当前看起来像这样:
ID V1 V2 ... V32
1 England Greece USA
2 England England China
3 China Greece Greece
4 England England England
.
.
.
Run Code Online (Sandbox Code Playgroud)
我想逐行计算(共)出现并且与顺序无关,以获得一个(共)出现矩阵,该矩阵说明边缘循环(例如英格兰 - 英格兰)的低频,这导致以下结果:
China England Greece USA
China 2 2 2 0
England 2 6 1 1
Greece 2 1 3 1
USA 0 1 1 1
Run Code Online (Sandbox Code Playgroud)
我曾经igraph得到一个共现的邻接矩阵。然而,它计算 - 正如预期的那样 - 相同两个对象的不超过两次交互,在某些情况下,我的值远低于按行/发布的对象的实际频率。
df <- data.frame(ID = c(1,2,3,4),
V1 = c("England", "England", "China", "England"),
V2 = c("Greece", "England", "Greece", "England"),
V32 = c("USA", "China", "Greece", "England"))
# remove ID column
df[1] <- list(NULL)
# calculate co-occurrences and return as dataframe
library(igraph)
library(Matrix)
countrydf <- graph.data.frame(df)
countrydf2 <- as_adjacency_matrix(countrydf, type = "both", edges = FALSE)
countrydf3 <- as.data.frame(as.matrix(forceSymmetric(countrydf2)))
Run Code Online (Sandbox Code Playgroud)
China England Greece USA
China 0 0 1 0
England 0 2 1 0
Greece 1 1 0 0
USA 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
我认为必须有一个简单的解决方案,使用base和/或dplyr和/或table和/或reshape2类似于[1]、[2]、[3]、[4]或[5]但到目前为止还没有解决任何问题,我无法根据我的需要调整代码。我也尝试使用[6]作为基础,但是,同样的问题也适用于此。
library(tidry)
library(dplyr)
library(stringr)
# collapse observations into one column
df2 <- df %>% unite(concat, V1:V32, sep = ",")
# calculate weights
df3 <- df2$concat %>%
str_split(",") %>%
lapply(function(x){
expand.grid(x,x,x,x, w = length(x), stringsAsFactors = FALSE)
}) %>%
bind_rows
df4 <- apply(df3[, -5], 1, sort) %>%
t %>%
data.frame(stringsAsFactors = FALSE) %>%
mutate(w = df3$w)
Run Code Online (Sandbox Code Playgroud)
如果有人能指出我正确的方向,我会很高兴。
可能有更好的方法来做到这一点,但请尝试:
library(tidyverse)
df1 <- df %>%
pivot_longer(-ID, names_to = "Category", values_to = "Country") %>%
xtabs(~ID + Country, data = ., sparse = FALSE) %>%
crossprod(., .)
df_diag <- df %>%
pivot_longer(-ID, names_to = "Category", values_to = "Country") %>%
mutate(Country2 = Country) %>%
xtabs(~Country + Country2, data = ., sparse = FALSE) %>%
diag()
diag(df1) <- df_diag
df1
Country China England Greece USA
China 2 2 2 0
England 2 6 1 1
Greece 2 1 3 1
USA 0 1 1 1
Run Code Online (Sandbox Code Playgroud)