更改信息时查找唯一用户
Finding Unique Users When Changing Info
我有以下数据:
dat <- data.frame(user_id = c(101,102,102,103,103,106),
phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203, 4030204))
我想计算独立用户数。如您所见,这里有 2 个唯一用户。所以,最终我想要创建的 table 如下:
user_id phone_number new_user_id
101 4030201 1
102 4030201 1
102 4030202 1
103 4030202 1
103 4030203 1
106 4030204 2
关于如何在 R 中计算这个的任何想法?或者用不同的语言,然后我可以将代码翻译成 R。
Updated02(需要进行一些小调整)
我不得不问两个问题才能解决它。如果您经常处理此类问题,则需要学习主要用于网络分析的 igraph
包。也许有一种更简单的方法可以做到这一点,但现在我认为它会做。让我们带您一探究竟:
library(dplyr)
library(purrr)
# In the firs chunk we iterate over every row of your data set to find out
# whether there is a connection between the corresponding rows and the others
map(1:nrow(dat), function(x) {
dat %>%
mutate(id = row_number()) %>%
pmap_lgl(., ~ {x <- unlist(dat[x,]);
any(x %in% c(...))})
}) %>%
exec(cbind, !!!.) %>%
as.data.frame() -> dat2
dat2 %>%
pmap(~ sub("V", "", names(dat2))[c(...)] %>% as.numeric()) -> ids
[[1]]
[1] 1 2
[[2]]
[1] 1 2 3
[[3]]
[1] 2 3 4
[[4]]
[1] 3 4 5
[[5]]
[1] 4 5 8
[[6]]
[1] 6
[[7]]
[1] 7
[[8]]
[1] 5 8
然后我们将所有相关的 id
分组在一起。对于这部分,我使用了我亲爱的朋友@det 和@Ian Campbell 提出的 因为我不知道如何使用 igraph
.
library(igraph)
map(ids, function(a) map_int(ids, ~length(base::intersect(a, .x)) > 0) * 1L) %>%
reduce(rbind) %>%
graph.adjacency() %>%
as.undirected() %>%
components() %>%
pluck("membership") %>%
split(seq_along(.), .) %>%
map(~unique(unlist(ids[.x]))) -> grouped_ids
$`1`
[1] 1 2 3 4 5 8
$`2`
[1] 6
$`3`
[1] 7
我们将所有相关的分组一次后,我们可以对我们的数据集进行分组:
dat %>%
mutate(id = row_number()) %>%
rowwise() %>%
mutate(grp = seq(length(grouped_ids))[map_lgl(grouped_ids, ~ id %in% .x)])
user_id phone_number id grp
1 101 4030201 1 1
2 102 4030201 2 1
3 102 4030202 3 1
4 103 4030202 4 1
5 103 4030203 5 1
6 106 4030204 6 2
7 107 4030205 7 3
8 111 4030203 8 1
数据
structure(list(user_id = c(101, 102, 102, 103, 103, 106, 107,
111), phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203,
4030204, 4030205, 4030203)), class = "data.frame", row.names = c(NA,
-8L))
稍微简化我朋友的
dat <- data.frame(user_id = c(101,102,102,103,103,106),
phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203, 4030204))
library(tidyverse)
library(igraph)
graph.data.frame(dat) %>%
components() %>%
pluck(membership) %>%
stack() %>%
set_names(c('GRP', 'user_id')) %>%
right_join(dat %>% mutate(user_id = as.factor(user_id)), by = c('user_id'))
GRP user_id phone_number
1 1 101 4030201
2 1 102 4030201
3 1 102 4030202
4 1 103 4030202
5 1 103 4030203
6 2 106 4030204
在dat
评论中给出,它给出
GRP user_id phone_number
1 1 101 4030201
2 1 102 4030201
3 1 102 4030202
4 1 103 4030202
5 1 103 4030203
6 2 106 4030204
7 3 107 4030205
8 1 111 4030203
这是一个igraph
选项
dat %>%
mutate(new_user_id = membership(components(graph_from_data_frame(.)))[as.character(user_id)])
这给出了
user_id phone_number new_user_id
1 101 4030201 1
2 102 4030201 1
3 102 4030202 1
4 103 4030202 1
5 103 4030203 1
6 106 4030204 2
我有以下数据:
dat <- data.frame(user_id = c(101,102,102,103,103,106),
phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203, 4030204))
我想计算独立用户数。如您所见,这里有 2 个唯一用户。所以,最终我想要创建的 table 如下:
user_id phone_number new_user_id
101 4030201 1
102 4030201 1
102 4030202 1
103 4030202 1
103 4030203 1
106 4030204 2
关于如何在 R 中计算这个的任何想法?或者用不同的语言,然后我可以将代码翻译成 R。
Updated02(需要进行一些小调整)
我不得不问两个问题才能解决它。如果您经常处理此类问题,则需要学习主要用于网络分析的 igraph
包。也许有一种更简单的方法可以做到这一点,但现在我认为它会做。让我们带您一探究竟:
library(dplyr)
library(purrr)
# In the firs chunk we iterate over every row of your data set to find out
# whether there is a connection between the corresponding rows and the others
map(1:nrow(dat), function(x) {
dat %>%
mutate(id = row_number()) %>%
pmap_lgl(., ~ {x <- unlist(dat[x,]);
any(x %in% c(...))})
}) %>%
exec(cbind, !!!.) %>%
as.data.frame() -> dat2
dat2 %>%
pmap(~ sub("V", "", names(dat2))[c(...)] %>% as.numeric()) -> ids
[[1]]
[1] 1 2
[[2]]
[1] 1 2 3
[[3]]
[1] 2 3 4
[[4]]
[1] 3 4 5
[[5]]
[1] 4 5 8
[[6]]
[1] 6
[[7]]
[1] 7
[[8]]
[1] 5 8
然后我们将所有相关的 id
分组在一起。对于这部分,我使用了我亲爱的朋友@det 和@Ian Campbell 提出的 igraph
.
library(igraph)
map(ids, function(a) map_int(ids, ~length(base::intersect(a, .x)) > 0) * 1L) %>%
reduce(rbind) %>%
graph.adjacency() %>%
as.undirected() %>%
components() %>%
pluck("membership") %>%
split(seq_along(.), .) %>%
map(~unique(unlist(ids[.x]))) -> grouped_ids
$`1`
[1] 1 2 3 4 5 8
$`2`
[1] 6
$`3`
[1] 7
我们将所有相关的分组一次后,我们可以对我们的数据集进行分组:
dat %>%
mutate(id = row_number()) %>%
rowwise() %>%
mutate(grp = seq(length(grouped_ids))[map_lgl(grouped_ids, ~ id %in% .x)])
user_id phone_number id grp
1 101 4030201 1 1
2 102 4030201 2 1
3 102 4030202 3 1
4 103 4030202 4 1
5 103 4030203 5 1
6 106 4030204 6 2
7 107 4030205 7 3
8 111 4030203 8 1
数据
structure(list(user_id = c(101, 102, 102, 103, 103, 106, 107,
111), phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203,
4030204, 4030205, 4030203)), class = "data.frame", row.names = c(NA,
-8L))
稍微简化我朋友的
dat <- data.frame(user_id = c(101,102,102,103,103,106),
phone_number = c(4030201, 4030201, 4030202, 4030202, 4030203, 4030204))
library(tidyverse)
library(igraph)
graph.data.frame(dat) %>%
components() %>%
pluck(membership) %>%
stack() %>%
set_names(c('GRP', 'user_id')) %>%
right_join(dat %>% mutate(user_id = as.factor(user_id)), by = c('user_id'))
GRP user_id phone_number
1 1 101 4030201
2 1 102 4030201
3 1 102 4030202
4 1 103 4030202
5 1 103 4030203
6 2 106 4030204
在dat
评论中给出,它给出
GRP user_id phone_number
1 1 101 4030201
2 1 102 4030201
3 1 102 4030202
4 1 103 4030202
5 1 103 4030203
6 2 106 4030204
7 3 107 4030205
8 1 111 4030203
这是一个igraph
选项
dat %>%
mutate(new_user_id = membership(components(graph_from_data_frame(.)))[as.character(user_id)])
这给出了
user_id phone_number new_user_id
1 101 4030201 1
2 102 4030201 1
3 102 4030202 1
4 103 4030202 1
5 103 4030203 1
6 106 4030204 2