Парный подсчет данных из длинного формата - PullRequest
0 голосов
/ 18 марта 2020

Пример данных
У меня есть следующие данные:

df <- data.frame(
  id = c('X1','X1','X1','X1','X2','X2','X2','X2'),
  pos = c(1,2,3,4,1,2,3,4),
  group = c(100,200,100,300,100,200,100,200)
)

Что выглядит следующим образом:

  id pos group
1 X1   1   100
2 X1   2   200
3 X1   3   100
4 X1   4   300
5 X2   1   100
6 X2   2   200
7 X2   3   100
8 X2   4   200

Что я пытаюсь сделать достижения
Я хочу построить эти данные, используя geom_segment(), где pos будет на оси X, а group на оси Y. Затем для каждого из этих сегментов я хочу посчитать, как часто они присутствуют в наборе данных (на основе столбца id). При выполнении этого для примера набора данных результат будет:

pos1 pos2 group1 group2 id.count
1    2    100    200    2  
2    3    200    100    2  
3    4    100    300    1  
3    4    100    200    1  

Я понятия не имею, как начать с этого, хотя я знаком с group_by из dplyr, я не могу понять, как построить первые четыре столбца.

Ответы [ 2 ]

1 голос
/ 18 марта 2020

Если порядок в вашем наборе данных такой же, как в вашем примере, вы можете попробовать это:

 library(dplyr)

 df %>% group_by(id) %>% 
        transmute(pos1 = pos, pos2 = lead(pos),
        group1 = group, group2 = lead(group)) %>%
        na.omit() %>% ungroup()%>%
        count(pos1, pos2, group1, group2, name = "id.count")
# A tibble: 4 x 5
#   pos1  pos2 group1 group2 id.count
#  <dbl> <dbl>  <dbl>  <dbl>    <int>
#     1     2    100    200        2
#     2     3    200    100        2
#     3     4    100    200        1
#     3     4    100    300        1
1 голос
/ 18 марта 2020

Я попробовал следующее, что работает, но интересно, есть ли более элегантное решение для этого:

# Simple stats
vals <- unique(df$pos)
min.val = min(vals)
max.val = max(vals)

# Combination
comb.df <- data.frame(
  pos1 = min.val:(max.val - 1),
  pos2 = (min.val + 1): max.val
)

# Combine
comb.df <- comb.df %>% 
  left_join(df %>% select(pos1 = pos, group1 = group, id )) %>%
  left_join(df %>% select(pos2 = pos, group2 = group, id ))

# Count
comb.df <- comb.df %>% 
  group_by(pos1, pos2, group1, group2) %>%
  summarise(n.ids = n_distinct(id))
...