r-根据第二列计算一列中元素之间的共出现次数,仅当第三列中元素不相等时才计算



我想计算数据帧df中列c中唯一元素的每个成对组合在列a的元素上共出现的频率,但另外,只有当列b中的各个值不相等时,即以列b中的不匹配为条件,才计算共出现的次数

a <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4)
b <- c(1,1,2,2,2,1,1,2,2,3,3,3,3,1,1,1,2,2,2,4)
c <- c(1,2,1,2,3,2,3,1,2,1,1,2,3,1,2,1,1,2,4,1) 
df <- as.data.frame(cbind(a,b,c))

在不考虑列b的情况下,我可以做以下操作来保留列c的每对元素,关于它们共同出现的a的元素数量

df <- unique(df[,c(1,3)])
df <- merge(df, df, by = "a")
df$count <- 1
df <- aggregate(count ~ ., df[, c(2:4)], sum)
df <- df[df$c.x != df$c.y,]

b中不匹配的附加条件下,只有一个区别:列c的元素2和4都出现在列a的元素4上,但在b中具有相同的值,因此不应计数为

c.x <- c(2,3,4,1,3,1,2,1)
c.y <- c(1,1,1,2,2,3,3,4)
count <- c(4,3,1,4,3,3,3,1)
result <- as.data.frame(cbind(c.x,c.y,count))

由于原始数据集很大(>1000000个观测值(,我欢迎快速解决方案,即不使用循环或合并。通常,我使用sparseMatrix()从三列数据帧创建共现矩阵

根据您的描述,我不确定这是否是您想要的,也不确定这会有多快,但这里有一种purrr的方法:

library(purrr)
split(df, c) %>%
combn(2, simplify = F) %>%
set_names(map(., ~ paste(names(.x), collapse = "_"))) %>%
map_int(~ merge(.x[[1]], .x[[2]], by = NULL) %>%
dplyr::filter(a.x == a.y && b.x != b.y) %>%
nrow())

退货:

1_2 1_3 1_4 2_3 2_4 3_4 
0  27   0  21   0   0 
# Data used:
df <- structure(list(a = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4), b = c(1, 1, 2, 2, 2, 1, 1, 2, 2, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2, 4), c = c(1, 2, 1, 2, 3, 2, 3, 1, 2, 1, 1, 2, 3, 1, 2, 1, 1, 2, 4, 1)), class = "data.frame", row.names = c(NA, -20L))

最新更新