Как изменить форму фрейма данных для создания двоичных комбинаций с использованием другого столбца в R

#r #sorting #dplyr #group-by #reshape

#r #сортировка #dplyr #группировка по #изменить форму

Вопрос:

У меня есть набор данных, который включает имена и компании, в которых они когда-либо работали.

 name     company
 A        Mazda
 B        Benz
 C        Mazda
 D        Toyota
 E        Benz
 F        Mazda
 E        BMW
 G        Benz
 A        Toyota
 C        Toyota
 B        BMW
 

Я хотел бы использовать dplyr и сортировать данные, показывая любую комбинацию двух имен, которые когда-либо работали в одной компании. Порядок имен не имеет значения, например, комбинация A и C не имеет разницы с комбинацией C и A. Таким образом, благоприятный результат будет

 name 1     name 2     company
 A            C         Mazda
 A            C         Toyota
 A            F         Mazda
 B            E         Benz
 B            E         BMW
 C            F         Mazda
 B            G         Benz
 E            G         Benz
 D            C         Toyota 
 A            C         Toyota
 

Ответ №1:

Вот решение, использующее purrr

 library(dplyr)
library(purrr)

# Function that take in a df that only contains one company names
company_combination <- function(data) {
  stopifnot(length(unique(data$company)) == 1)
  # generate a empty tibble if there only one record for the company
  if (nrow(data) == 1) { 
    names_comb <- tibble()
  } else {
    # get the company name
    company <- first(data[["company"]])
    # generate name combination from the name list and put it into tibble of two columns
    names_comb <- as_tibble(t(combn(x = unique(data[["name"]]), m = 2)))
    # change column names to name_1 amp; name_2
    names(names_comb) <- c("name_1", "name_2")
    # Add the company name into the new name combination df and return the result
    names_comb %<>% mutate(company = company)
  }
  names_comb
}

# Here there are three steps
df %>%
  # 1st split original data into list of dataframe group by company
  split(.$company) %>%
  # Then apply the company_combination function for each company df
  # Result of this command is a new list of dataframe as result of the function
  map(., company_combination) %>%
  # Then bind them all together back to one dataframe.
  bind_rows()
 

Вот результат:

 # A tibble: 10 x 3
   name_1 name_2 company
   <chr>  <chr>  <chr>  
 1 B      E      Benz   
 2 B      G      Benz   
 3 E      G      Benz   
 4 B      E      BMW    
 5 A      C      Mazda  
 6 A      F      Mazda  
 7 C      F      Mazda  
 8 A      C      Toyota 
 9 A      D      Toyota 
10 C      D      Toyota 
 

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

1. ваш вывод отличается от моего, вы создали другой df?

2. Я использую те же данные, которые вы предоставили. Результат отличается, но я думаю, что мой более полный — если у вас в компании три человека, у вас должно быть 3 комбинации из 2. При выборке выводится только 2 комбинации.

3. спасибо, вы правы, я собираюсь запустить ваш код и буду держать вас в курсе.

4. Я получаю эту ошибку `Ошибка в .f(.x[[i]], …) : длина (уникальная (данные $ company)) == 1 не соответствует ДЕЙСТВИТЕЛЬНОСТИ` . Я вижу, вы упомянули ту же ошибку, но, очевидно, у меня больше 1 в некоторых компаниях или, скажем, у меня есть дубликаты в компаниях

5. Можете ли вы поделиться, какой код привел к этому? У вас есть строка split ? И убедитесь, что вы настроили функцию так, чтобы она соответствовала имени столбца в ваших данных.