R 有效地将所有共关联从关联TIBLE转换为关联TIBLE
我有一个TIBLE,它编码哪些人喜欢哪些食物。有约300万排,约9200人,约2k种食物。我计算了每种食物的受欢迎程度(有多少%的人喜欢它)。由此我计算出每一种食物的受欢迎程度(喜欢食物的概率是喜欢食物的概率的1倍,喜欢食物的概率是喜欢食物的概率的2倍)。现在我想计算每一种食物的受欢迎程度,但我已经尝试了几种方法,每次Rstudio都会崩溃。所以,我认为我需要找到一种更有效的方法(也许是从记忆的角度)来做这件事。我是这样做的。很抱歉,代码太多了,但我不认为有任何不必要的步骤,我已经尝试使用好的名称,这样就可以清楚地知道每一位的作用R 有效地将所有共关联从关联TIBLE转换为关联TIBLE,r,tidyverse,tidyr,purrr,tibble,R,Tidyverse,Tidyr,Purrr,Tibble,我有一个TIBLE,它编码哪些人喜欢哪些食物。有约300万排,约9200人,约2k种食物。我计算了每种食物的受欢迎程度(有多少%的人喜欢它)。由此我计算出每一种食物的受欢迎程度(喜欢食物的概率是喜欢食物的概率的1倍,喜欢食物的概率是喜欢食物的概率的2倍)。现在我想计算每一种食物的受欢迎程度,但我已经尝试了几种方法,每次Rstudio都会崩溃。所以,我认为我需要找到一种更有效的方法(也许是从记忆的角度)来做这件事。我是这样做的。很抱歉,代码太多了,但我不认为有任何不必要的步骤,我已经尝试使用好的名
library(tidyverse)
lu <- compose(length, unique)
set.seed(37212)
num_people <- 92000
num_foods <- 2000
num_prefs <- 3e6
person <- sample(x = num_people, size = num_prefs, replace = TRUE)
food <- sample(x = num_foods, size = num_prefs, replace = TRUE)
tibble(person = factor(person, ordered = TRUE),
food = factor(food, ordered = TRUE)) %>%
distinct() ->
food_prefs
stopifnot(lu(food_prefs$person) == num_people)
stopifnot(lu(food_prefs$food) == num_foods)
food_prefs %>%
group_by(food) %>%
summarise(p = n()/num_people) %>%
print() ->
food_popularities
food_popularities %>%
mutate(food1 = food,
food2 = food) %>%
expand(food1, food2) %>%
filter(food1 < food2) %>%
print() ->
food_pairs
food_pairs %>%
inner_join(food_popularities,
by = c('food1' = 'food')) %>%
inner_join(food_popularities,
by = c('food2' = 'food'),
suffix = c('1', '2')) %>%
mutate(p_joint = p1*p2) %>%
print() ->
pairwise_popularity_expected
food_prefs %>%
group_by(food) %>%
summarise(person_list = list(person)) %>%
print() ->
food_liker_lists
# the line here that starts with 'mutate' is what crashes my computer
food_pairs %>%
inner_join(food_liker_lists,
by = c('food1' = 'food')) %>%
inner_join(food_liker_lists,
by = c('food2' = 'food'),
suffix = c('1', '2')) %>%
mutate(joint_list = map2(person_list1,
person_list2,
intersect),
num_joint = map_int(joint_list, length))
并会见了:
m%*%t(m)中的错误:
Cholmod错误“问题太大”,位于文件../MatrixOps/Cholmod_ssmult.c,第222行我认为最好使用稀疏矩阵而不是密集矩阵,例如
矩阵
包。稀疏矩阵是非常高效的内存,它允许您计算邻接矩阵(如果您反向操作,则食物或人的共存)。然后你可以把矩阵分解成一个成对的列表
A <- spMatrix(ncol = length(unique(food_prefs$person)),
nrow = length(unique(food_prefs$food)),
j = as.numeric(factor(food_prefs$person)),
i = as.numeric(factor(food_prefs$food)),
x = rep(1, nrow(food_prefs)))
rownames(A) <- levels(factor(food_prefs$food))
colnames(A) <- levels(factor(food_prefs$person))
adj <- A %*% t(A)
food_pairs <- data.frame(food1=rownames(adj)[row(adj)],food2=colnames(adj)[col(adj)],num_joint=as.numeric(adj))
food_pairs <- food_pairs[food_pairs$food1 != food_pairs$food2, ]
head(food_pairs)
# food1 food2 num_joint
# 2 F10 F1 23
# 3 F100 F1 26
# 4 F1000 F1 25
# 5 F1001 F1 19
# 6 F1002 F1 27
# 7 F1003 F1 34
A我认为最好使用稀疏矩阵而不是密集矩阵,例如矩阵
包。稀疏矩阵是非常高效的内存,它允许您计算邻接矩阵(如果您反向操作,则食物或人的共存)。然后你可以把矩阵分解成一个成对的列表
A <- spMatrix(ncol = length(unique(food_prefs$person)),
nrow = length(unique(food_prefs$food)),
j = as.numeric(factor(food_prefs$person)),
i = as.numeric(factor(food_prefs$food)),
x = rep(1, nrow(food_prefs)))
rownames(A) <- levels(factor(food_prefs$food))
colnames(A) <- levels(factor(food_prefs$person))
adj <- A %*% t(A)
food_pairs <- data.frame(food1=rownames(adj)[row(adj)],food2=colnames(adj)[col(adj)],num_joint=as.numeric(adj))
food_pairs <- food_pairs[food_pairs$food1 != food_pairs$food2, ]
head(food_pairs)
# food1 food2 num_joint
# 2 F10 F1 23
# 3 F100 F1 26
# 4 F1000 F1 25
# 5 F1001 F1 19
# 6 F1002 F1 27
# 7 F1003 F1 34
A如果你只看实际上同时出现的食物组合,它更适合:
food_prefs %>%
inner_join(food_prefs, by = 'person') %>%
filter(food.x < food.y) %>%
count(food.x, food.y)
food\u prefs%>%
内部联接(食物优先,由='人')%>%
过滤器(食品x<食品y)%>%
计数(食物x,食物y)
#tible:1999000 x 3
食物
1 1 2 19
2 1 3 21
3 1 4 19
4 1 5 22
5 1 6 13
6 1 7 21
7 1 8 20
8 1 9 22
9 1 10 23
10 1 11 21
#…还有1998990行
如果你只看实际同时出现的食物组合,它更适合:
food_prefs %>%
inner_join(food_prefs, by = 'person') %>%
filter(food.x < food.y) %>%
count(food.x, food.y)
food\u prefs%>%
内部联接(食物优先,由='人')%>%
过滤器(食品x<食品y)%>%
计数(食物x,食物y)
#tible:1999000 x 3
食物
1 1 2 19
2 1 3 21
3 1 4 19
4 1 5 22
5 1 6 13
6 1 7 21
7 1 8 20
8 1 9 22
9 1 10 23
10 1 11 21
#…还有1998990行