我有一个包含留言板信息的数据框。数据如下所示:
require(dplyr)
require(tidyr)
df <- data.frame(author = c(2,4,8,16,32,64,128,256,512,1024),
topic = c(101,101,101,101,301,301,501,501,501,501),
time = c("2014-08-16 20:20:11", "2014-08-16 21:10:00", "2014-08-17 06:30:10",
"2014-08-17 10:08:32", "2014-08-20 22:23:01","2014-08-20 23:03:03",
"2014-08-25 17:05:01", "2014-08-25 19:15:10", "2014-08-25 20:07:11",
"2014-08-25 23:59:59"))
我想按主题找到作者的所有独特组合。我的目标是创建一个无向图,其边缘按主题和时间范围分类。我使用以下代码来实现此目的:
test <- df %>% group_by(topic) %>% expand(nesting(author), author)
print(test, n = 20)
# A tibble: 36 x 3
# Groups: topic [3]
topic author author1
<dbl> <dbl> <dbl>
1 101. 2. 2.
2 101. 2. 4.
3 101. 2. 8.
4 101. 2. 16.
5 101. 4. 2.
6 101. 4. 4.
7 101. 4. 8.
8 101. 4. 16.
9 101. 8. 2.
10 101. 8. 4.
11 101. 8. 8.
12 101. 8. 16.
13 101. 16. 2.
14 101. 16. 4.
15 101. 16. 8.
16 101. 16. 16.
17 301. 32. 32.
18 301. 32. 64.
19 301. 64. 32.
20 301. 64. 64.
我需要帮助两件事:
start
=最早的主题帖子(使用mutate,min = min(time))duration
主题(关于主题的最后一篇文章的时间减去关于主题的第一篇文章的时间,使用mutate duration = max(time) - min(time))posts
的计数(使用汇总)? 答案 0 :(得分:0)
我用这种方式解决了我的问题:
test <- df %>% group_by(topic) %>%
mutate(posts=n(), start=min(time), duration=(max(time)-min(time))/3600) %>%
expand(nesting(author), author, posts, start, duration) %>% filter(author != author1)
test
# A tibble: 36 x 6
# Groups: topic [3]
topic author author1 posts start duration
<dbl> <dbl> <dbl> <int> <dttm> <dbl>
2 101. 2. 4. 4 2014-08-16 20:20:11 13.8
3 101. 2. 8. 4 2014-08-16 20:20:11 13.8
4 101. 2. 16. 4 2014-08-16 20:20:11 13.8
5 101. 4. 2. 4 2014-08-16 20:20:11 13.8
7 101. 4. 8. 4 2014-08-16 20:20:11 13.8
8 101. 4. 16. 4 2014-08-16 20:20:11 13.8
9 101. 8. 2. 4 2014-08-16 20:20:11 13.8
10 101. 8. 4. 4 2014-08-16 20:20:11 13.8
# ... with 26 more rows
仍然需要找出交换组合!
答案 1 :(得分:0)
您不一定要使用tidyr::expand()
(似乎是左连接)来尝试生成组合,您似乎正在获得所有置换代替:特别是,不需要的自我组合,以及与author1,author2的组合交换(即排列)。同样地,内置base::expand.grid()
进行排列而不是组合。
使用内置combn()
(utils::combn()
中的内容)。
dplyr
groupby
combn
上存在许多现有问题,您可以通过简单的搜索找到它们。
尝试发布工作代码但我不太了解tidyr
,我尝试过的所有内容都没有工作或语法错误。 expand
想要一个数据帧,然后引用变量。因此%>% expand(author, author)
再次为您提供所有排列,而不仅仅是组合。 %>% complete(...)
似乎毫无用处。我认为您需要使用tidyr语法在该分组级别combn
上调用author
。对于每个分组级别,这可能需要是一个嵌套的子语句,其中tidyr等同于do.call。
答案 2 :(得分:0)
最终解决方案:
time <- df %>% group_by(topic) %>% mutate(posts = n(), start = min(time), duration = (max(time) - min(time))/3600) %>% distinct(topic,start,duration)
combo <- df %>% group_by(topic) %>% do(data.frame(t(combn(.$author,2))))
edges <- right_join(combo, time)
edges
# A tibble: 13 x 5
# Groups: topic [?]
topic X1 X2 start duration
<dbl> <dbl> <dbl> <dttm> <time>
1 101. 2. 4. 2014-08-16 20:20:11 13.8058333333333
2 101. 2. 8. 2014-08-16 20:20:11 13.8058333333333
3 101. 2. 16. 2014-08-16 20:20:11 13.8058333333333
4 101. 4. 8. 2014-08-16 20:20:11 13.8058333333333
5 101. 4. 16. 2014-08-16 20:20:11 13.8058333333333
6 101. 8. 16. 2014-08-16 20:20:11 13.8058333333333
7 301. 32. 64. 2014-08-20 22:23:01 0.667222222222222
8 501. 128. 256. 2014-08-25 17:05:01 6.91611111111111
9 501. 128. 512. 2014-08-25 17:05:01 6.91611111111111
10 501. 128. 1024. 2014-08-25 17:05:01 6.91611111111111
11 501. 256. 512. 2014-08-25 17:05:01 6.91611111111111
12 501. 256. 1024. 2014-08-25 17:05:01 6.91611111111111
13 501. 512. 1024. 2014-08-25 17:05:01 6.91611111111111
答案 3 :(得分:0)
我发现了iterpc包。它很快并且组合起来。这是我的示例代码:
df <- data.frame(author_id = c(2,4,8,16,32,16,128,256,512,8),
topic_id = c(101,101,101,101,301,301,501,501,501,501),
time = as.POSIXct(c("2014-08-16 20:20:11", "2014-08-16 21:10:00", "2014-08-17 06:30:10",
"2014-08-17 10:08:32", "2014-08-20 22:23:01","2014-08-20 23:03:03",
"2014-08-25 17:05:01", "2014-08-25 19:15:10", "2014-08-25 20:07:11",
"2014-08-25 23:59:59")))
首先,我创建一个唯一的节点列表(图顶点)
node <- df %>% distinct(author_id, vendor) %>% rename(id = author_id)
然后我使用iterpc创建我的边缘列表,如下所示:
library(iterpc)
edge <- df %>% group_by(topic_id) %>% do(data.frame(getall(iterpc(table(.$author_id), 2, replace =TRUE)))) %>%
filter(X1 != X2) %>% rename(from = X1, to = X2) %>% select(to, from, topic_id)
我完成了我的图表:
library(igraph)
test_net <- graph_from_data_frame(d = edge, directed = F, vertices = node)
plot(test_net)