我是R语言的新手,目前正在处理一份包含32列和约200,000行的协作数据,该数据以边列表示。我希望创建一个基于国家间互动的(共现)矩阵。但是,我想通过对象总数来计算交互次数。
预期结果的基本示例
如果在一行中"England"出现了三次而"China"只出现了一次,则结果应该是以下矩阵。
England China
England 3 3
China 3 1
可重复的示例
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"))
因此,一个示例数据框目前看起来像这样:
ID V1 V2 ... V32
1 England Greece USA
2 England England China
3 China Greece Greece
4 England England England
.
.
.
预期结果
我想按行计算(共同)出现次数,而不考虑顺序,以获得一个(共同)出现矩阵,可以解决边缘环的低频率问题(例如英格兰-英格兰),从而得出以下结果:
China England Greece USA
China 2 2 2 0
England 2 6 1 1
Greece 2 1 3 1
USA 0 1 1 1
目前为止已经尝试的方法
我已经使用了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)))
China England Greece USA
China 0 0 1 0
England 0 2 1 0
Greece 1 1 0 0
USA 0 0 0 0
我假设使用
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)
如果有人能指点我正确的方向,我会很高兴。
arules
包中的函数来处理数据,避免过多的额外操作。 - emilliman5