Разбить двойные столбцы на отдельные столбцы и объединить одноименные столбцы - PullRequest
2 голосов
/ 30 января 2020

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

Это мой ввод:

structure(list(`A1-A2` = c(2, 1, 1), `A1-A3` = c(2, 1, 2)), row.names = c(NA, 
-3L), class = c("tbl_df", "tbl", "data.frame"))

# A tibble: 3 x 2
  `A1-A2` `A1-A3`
    <dbl>   <dbl>
1       2       2
2       1       1
3       1       2

Для одного столбца я могу продемонстрировать, что я хочу сделать, но не для нескольких:

data %>% 
  separate(`A1-A2`, into = c("A1", "A2"), sep = ":") %>% 
  mutate_at(.vars = c(1:2), as.numeric) %>% 
  mutate(A2 = A1 -1) %>% 
  mutate(A1 = ifelse(A1 == 2, 0, A1))

# A tibble: 3 x 3
     A1    A2 `A1-A3`
  <dbl> <dbl>   <dbl>
1     0     1       2
2     1     0       1
3     1     0       2
  • Это разбивает столбец A1-A2 на два отдельных столбца A1 и A2.
  • Если его значение равно 1, устанавливает 1 в левом столбце (A1)
  • Если его значение равно 2, устанавливает 1 в правом столбце (A2) Это работает только, как вы можете видеть в приведенном выше коде, для разбиения 1 двойного столбца.

В итоговой таблице должны быть окончательно собраны все победные баллы для каждого столбца, например:

# A tibble: 1 x 3
     A1    A2    A3
1     3     1     2

Два вызова:

  1. Как сформулировать мой код в обобщенном формате c для любого количества двойных столбцов?

  2. Как избежать проблем, поскольку несколько разделенных столбцов иметь одно и то же имя (например, когда двойные столбцы A1-A2, A1-A3, A2-A3 разделены, они будут иметь A1, A2, A3, встречающиеся дважды) ??

Подходы в tidyverse (purrr::map) предпочтительнее, но я Я открыт для других решений.

Хитрость, не так ли?

1 Ответ

1 голос
/ 30 января 2020

Я собрал это решение с помощью @akrun, который вдохновил использовать pivot_longer и mutate с case_when. Если у кого-нибудь есть более элегантное или более короткое решение, пожалуйста, пишите!

data
# A tibble: 3 x 2
  `A1-A2` `A1-A3`
    <dbl>   <dbl>
1       2       2
2       1       1
3       1       2

comparisons <- data %>%
  pivot_longer(everything()) %>% 
  separate(name, c("V1", "V2"), sep = "-") %>% 
  mutate(win = case_when(value == 2 ~ V2, TRUE ~ V1)) %>% 
  select(-value) %T>% print 

# A tibble: 6 x 3
  V1    V2    win  
  <chr> <chr> <chr>
1 A1    A2    A2   
2 A1    A3    A3   
3 A1    A2    A1   
4 A1    A3    A1   
5 A1    A2    A1   
6 A1    A3    A3  

scores <- comparisons %>% 
  group_by(win) %>% 
  tally() %>% 
  pivot_wider(names_from = win, values_from = n) %T>% print 


# A tibble: 1 x 3
     A1    A2    A3
  <int> <int> <int>
1     3     1     2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...