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

#r #list #dataframe #sum

#r #Список #фрейм данных #сумма

Вопрос:

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

dput(head(list1)):

 list(FEB_GAMES = c(GAME1 = c("Stan", "Kenny", "Cartman", "Kyle", 
"Butters"), GAME2 = c("Kenny", "Cartman", "Kyle", "Butters")), 
MAR_GAMES = c(GAME3 = c("Stan", "Kenny", "Cartman", "Butters"
), GAME4 = c("Kenny", "Cartman", "Kyle", "Butters")))
  

dput(head(list2)):

 list(first = c("Stan", "Kenny", "Cartman", "Kyle", "Butters", 
"Kenny", "Cartman", "Kyle", "Butters"), second = c("Stan", "Kenny", 
"Cartman", "Wendy", "Ike"), third = c("Randy", "Randy", "Randy", 
"Randy"))
  

Я хотел бы превратить эти два списка в один большой data.frame / matrix. Имена строк будут из list1 (GAME1, GAME2, GAME3, GAME4). Имена столбцов будут именами списка 2 (первый, второй, третий). Информация в матрице будет целым числом, которое относится к количеству раз, когда общий символ встречается в обоих списках. например, GAME1xfirst содержит 9 общих символов, в то время как GAME1xthird содержит 0.


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

         first  second  third
GAME1   9      3       0
GAME2   8      2       0
GAME3   8      3       0
GAME4   8      2       0
  

Таким образом, значения в [1,1] будут представлять собой сумму раз, когда общий символ встречается как в списке GAME1 из списка 1, так и в первом списке, найденном в list2.

Примечание. Списки как в списке 1, так и в списке 2 имеют разное количество значений.

Ответ №1:

Как насчет …

 sapply(l2, function(x) {
  sapply(unlist(l1, recursive = FALSE), function(y) sum(x %in% y))
})
#                 first second third
# FEB_games.GAME1     9      3     0
# FEB_games.GAME2     8      2     0
# MAR_games.GAME3     7      3     0
# MAR_games.GAME4     8      2     0
  

Хотя, возможно, это не самый эффективный подход.

Комментарии:

1. Этот метод сработал. Приведенный выше ответ tidyverse был значительно быстрее. Приветствия.

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

Ответ №2:

Одним из вариантов было бы сначала выровнять ‘list1’, выполнить merge после преобразования в data.frame , а затем выполнить table

 list1a <- do.call(c, list1)
names(list1a) <- sub(".*\.", "", names(list1a))
out <- table(merge(stack(list1a), stack(list2), by = 'values')[-1])
names(dimnames(out)) <- NULL
out
#      first second third
#GAME1     9      3     0
#GAME2     8      2     0
#GAME3     7      3     0
#GAME4     8      2     0
  

Мы также можем сделать это в tidyverse , используя ту же логику

 library(tidyverse)
list1 %>% 
    flatten %>% 
    enframe %>% 
    unnest %>% 
    full_join(list2 %>% 
                enframe %>%
                unnest, by = 'value') %>% 
    select(-value) %>% 
    count(name.x, name.y) %>% 
    spread(name.y, n, fill = 0) %>%
    filter(!is.na(name.x))
# A tibble: 4 x 4   
#  name.x first second third
#  <chr>  <dbl>  <dbl> <dbl>
#1 GAME1      9      3     0
#2 GAME2      8      2     0
#3 GAME3      7      3     0
#4 GAME4      8      2     0
  

данные

 list1 <- list(FEB_games = list(GAME1 = c("Stan", "Kenny", "Cartman", "Kyle", 
"Butters"), GAME2 = c("Kenny", "Cartman", "Kyle", "Butters")), 
MAR_games = list(GAME3 = c("Stan", "Kenny", "Cartman", "Butters"
), GAME4 = c("Kenny", "Cartman", "Kyle", "Butters")))

list2 <- list(first = c("Stan", "Kenny", "Cartman", "Kyle", "Butters", 
 "Kenny", "Cartman", "Kyle", "Butters"), second = c("Stan", "Kenny", 
 "Cartman", "Wendy", "Ike"), third = c("Randy", "Randy", "Randy", 
"Randy"))
  

Комментарии:

1. Получение ошибки на первом шаге. в: list1a <- do.call(c, list1). выход: ошибка в do.call(c, list1) : ‘что’ должно быть функцией или символьной строкой.

2. Если вы уже определили c какой-либо идентификатор объекта, поместите его в кавычки do.call("c" или используйте обратные кавычки

3. Я не совсем уверен, что вы подразумеваете под идентификатором объекта. Это символ, который мы ищем, или функция?

4. @Krutik Я имел в виду, что если вы создали объект, подобный c <- 1:5 или что-то в этом роде, это может вызвать проблему. В любом случае, решение основано на вашем dput , поэтому структура не будет проблемой

5. @Krutik Можете ли вы попробовать первый метод с данными из моего поста, то есть только с заголовком, просто любопытно, почему он получил ошибку