Подсчет строк, содержащих комбинации в кадре данных в R - PullRequest
0 голосов
/ 01 августа 2020

Предполагая, что у меня есть следующий фрейм данных, состоящий из символов от 'a' до 'e':

df <- data.frame(P1 = c("a","b","c"), P2 = c("b","c","d"), P3 = c("e","a","e"))

  P1 P2 P3
1  a  b  e
2  b  c  a
3  c  d  e

Я хочу подсчитать количество строк фрейма данных, содержащих каждую комбинацию (размер 2) от «а» до «е». Итак, в этом случае существует 10 различных (размер 2) комбинаций от 'a' до 'e'.

t(combn(c("a","b","c","d","e"),2))

    [,1] [,2]
 [1,] "a"  "b" 
 [2,] "a"  "c" 
 [3,] "a"  "d" 
 [4,] "a"  "e" 
 [5,] "b"  "c" 
 [6,] "b"  "d" 
 [7,] "b"  "e" 
 [8,] "c"  "d" 
 [9,] "c"  "e" 
[10,] "d"  "e" 

2 строки имеют комбинацию «a» и «b», 1 строка имеет комбинацию « a "&" c ", ни в одной строке нет комбинации" a "&" d "и так далее ......... в конечном итоге я хочу, чтобы фрейм данных выглядел так:

   X1 X2 Count
1   a  b     2
2   a  c     1
3   a  d     0
4   a  e     ..
......... etc

Любая помощь по этому поводу будет принята с благодарностью, я думал, что dplyr или подобное может иметь что-то подходящее, но мне не удалось разработать простой подход без затрат времени l oop или аналогичного.

1 Ответ

2 голосов
/ 01 августа 2020

Вы можете получить данные в длинном формате и создать комбинации для каждой строки, подсчитать комбинации и объединить их с данными, которые мы создали для всех комбинаций, чтобы получить пропущенные значения.

library(dplyr) #dplyr >= 1.0.0
library(tidyr)

ref_data <- as.data.frame(t(combn(unique(unlist(df)),2)))

df %>%
  mutate(row = row_number()) %>%
  pivot_longer(cols = -row) %>%
  group_by(row) %>%
  summarise(value = combn(sort(value), 2, toString)) %>%
  separate(value, c('V1', 'V2'), sep = ", ") %>%
  ungroup %>%
  count(V1, V2) %>%
  right_join(ref_data, by = c('V1', 'V2')) %>%
  mutate(n = replace_na(n, 0))


# A tibble: 10 x 3
#   V1    V2        n
#   <chr> <chr> <dbl>
# 1 a     b         2
# 2 a     c         1
# 3 a     e         1
# 4 b     c         1
# 5 b     e         1
# 6 c     d         1
# 7 c     e         1
# 8 d     e         1
# 9 a     d         0
#10 b     d         0
...