Подсчет повторяющихся составов в R - PullRequest
2 голосов
/ 27 апреля 2019

Я запускаю симуляцию и создаю 10000 составов.Я хочу подсчитать количество созданных составов.Например, здесь есть 5 составов ...

col_1 <- c("Mary", "Jane", "Latoya", "Sandra", "Ebony", "Jada")
col_2 <- c("Jack", "Malik", "Brett", "Demetrius", "Jalen","David")
col_3 <- c("Mary", "Jane", "Latoya", "Sandra", "Ebony", "Jada")
col_4 <- c("Katie", "Emily", "Tara", "Imani", "Molly", "Claire")
col_5 <- c("Mary", "Jane", "Latoya", "Sandra", "Ebony", "Jada")
df <- data.frame(col_1, col_2, col_3,col_4,col_5)

Я хотел бы получить результат порядка ...

Состав A = col_1, col_3, col5 = 3

Состав B = col_2 = 1

Состав C = col_5 = 1

Я ударился головой о стену, исследуя пакет dplyr для решения.Любая помощь будет оценена.Спасибо.

Ответы [ 3 ]

2 голосов
/ 28 апреля 2019

вот единственное решение tidyverse, где мы упорядочиваем все столбцы, сворачиваем, принимаем уникальные значения, транспонируем и группируем, чтобы получить счет. Такой подход дает и членам команды.

library(tidyverse)

df2 <- df %>%
  arrange_all() %>%
  mutate_all(funs(paste0(., collapse = ","))) %>% 
  distinct() %>% 
  t() %>%
  as.data.frame %>%
  mutate(col       = colnames(df)) %>% 
  group_by(team    = V1) %>% 
  summarise(count  = n(), 
            lineup = paste(col, collapse = ","))


print(df2)
# A tibble: 3 x 3
  team                                   count lineup           
  <fct>                                  <int> <chr>            
1 Ebony,Jada,Jane,Latoya,Mary,Sandra         3 col_1,col_3,col_5
2 Jalen,David,Malik,Brett,Jack,Demetrius     1 col_2            
3 Molly,Claire,Emily,Tara,Katie,Imani        1 col_4    
1 голос
/ 28 апреля 2019

Сначала мы убедимся, что уровни во всех столбцах фрейма данных совпадают, и убираем их, чтобы получить числовые значения.

(d2 <- sapply(d, function(x) as.numeric(factor(x, levels=sort(unique(unlist(d)))))))
#      col_1 col_2 col_3 col_4 col_5
# [1,]     5    10     5    16     5
# [2,]     3    12     3    14     3
# [3,]     4     7     4    18     4
# [4,]     6     9     6    15     6
# [5,]     1    11     1    17     1
# [6,]     2     8     2    13     2

Затем мы можем применить toString к столбцам, разложить их на множители и разделитьих на уровне факторов;нам нужны только names,

n <- lapply(split(m <- factor(apply(d2, 2, toString)), m), names)

, что на самом деле является результатом того, что мы rbind вместе с их length s.

res <- do.call(rbind, lapply(n, function(x) cbind(toString(x), length(x))))
res
#     [,1]                  [,2]
# [1,] "col_2"               "1" 
# [2,] "col_4"               "1" 
# [3,] "col_1, col_3, col_5" "3" 

Наконец, мы можем захотетьчтобы придать матрице какой-то смысл dimnames.

dimnames(res) <- list(paste("Lineup", LETTERS[1:nrow(res)]), c("col", "n"))
res
#            col                   n  
# Lineup A "col_2"               "1"
# Lineup B "col_4"               "1"
# Lineup C "col_1, col_3, col_5" "3"

Примечание: Если у вас более 26 составов, вы можете захотеть сделать просто 1:nrow(res) вместо LETTERS[1:nrow(res)].

1 голос
/ 27 апреля 2019

Это было бы моим решением:

df_t <- df %>% 
  # Transpose the dataset, make sure people are sorted alphabetically
  gather(lineup_number, person_name) %>% # Lineup/Person Level
  arrange(lineup_number, person_name) %>% # Arrange alphabetically
  group_by(lineup_number) %>% 
  mutate(person_order = paste0("person", row_number())) %>%  
  ungroup() %>% 
  spread(person_order, person_name) # Row: Lineup. Column: Person

df_t %>% 
  select(starts_with("person")) %>% 
  group_by_all() %>% 
  summarise(num_lineups = n())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...