如何将纵向数据转换为连接数据?

How to convert longitudal data to connection data?

我有以下形式的数据:

id state
1  s_1
1  s_2
1  s_3
2  s_1
2  s_3
3  s_1
3  s_2

我想将它放在连接数据框中:

source target freq
s_1    s_2    2
s_1    s_3    1
s_2    s_3    1

我已经知道我可以使用 plyr::count() 计算频率,但是如何将数据重排为源和目标类型?

我相信你可以用 dplyr 试试这个。如评论中所述,使用 combn 在每个 id 中获取对组合。之后,按源和目标分组,您可以 summarise 并获得每个组合的频率。

library(dplyr)

df %>%
  group_by(id) %>%
  do(as.data.frame(t(combn(.$state, m = 2)))) %>%
  setNames(c("id", "source", "target")) %>%
  group_by(source, target) %>%
  summarise(freq = n())

输出

  source target  freq
  <chr>  <chr>  <int>
1 s_1    s_2        2
2 s_1    s_3        2
3 s_2    s_3        1

我认为@Ben 的解决方案是我们在这里可以实现的最清晰的解决方案,但为了勤奋,我根据评论和使用 for 循环创建了我的解决方案:

res <- data.frame(source=NA, target=NA)

for (i in 1:unique(df$id){
  df_grouped <- df[df$id == i,]
  for (j in 1:nrow(df_grouped)){
    source <- df_grouped[j, "state"]
    target <- df_grouped[j+1, "state"]
    res <- rbind(res, cbind(source,target))
  }
}
res <- res[complete.cases(res),]
res <- plyr::count(res)
res