Как вытащить несколько строк в столбцы? - PullRequest
1 голос
/ 11 октября 2019

Рассмотрим следующий фрейм данных:

data_frame(
col1 = c("2017", "June",   "New", 10, 30),
col2 = c("2018", "July",   "Old", 20, 50),
name = c(NA, NA, NA, "dog", "cat")
)

# A tibble: 5 x 3
  col1  col2  name 
1 2017  2018  NA   
2 June  July  NA   
3 New   Old   NA   
4 10    20    dog  
5 30    50    cat  

Я хотел бы преобразовать его в этот вывод:

## Year Month  Type name Amount
## 2017 June   New  dog  10
## 2018 July   Old  dog  20
## 2017 June   New  cat  30
## 2018 July   Old  cat  50

Я пытался использовать pivot дольше, но это трудное времявыполнение нескольких строк , а также обработка мертвого пространства с помощью NA.

1 Ответ

1 голос
/ 11 октября 2019

Я решил это, выделив 3 типа данных, которые все разбиты на один фрейм данных, а затем разделил их. Как сказано выше в @jdobres, это может не выходить за рамки этого игрушечного примера, но должно быть началом.

Из того, что я могу сказать, у вас есть 3 типа данных, которые вы можете извлечь на основе поиска по регулярным выражениям в col1:

  1. Годы, обозначенные ^20\\d{2}$ (необходимо откорректировать, если указать 19xx лет и т. Д.
  2. Месяцы, обозначенные нецифровыми символами
  3. Имена, идентифицируемые либо по типу значения в col1, либо по не- NA name

Отфильтруйте и измените их, чтобы их данные соответствовали формам, показанным в желаемом выводе:

library(dplyr)
library(tidyr)

yrs_df <- df %>% 
  filter(grepl("^20\\d{2}$", col1)) %>%
  gather(key, value = year) %>%
  filter(!is.na(year))

name_df <- df %>%
  filter(!is.na(name)) %>%
  gather(key, value, -name)

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

month_df <- df %>%
  filter(grepl("^\\D", col1)) %>%
  mutate(col_type = row_number()) %>%
  gather(key, value, -col_type) %>%
  filter(!is.na(value)) %>%
  spread(key = col_type, value, sep = "") %>%
  rename(month = col_type1, type = col_type2)

yrs_df
#> # A tibble: 2 x 2
#>   key   year 
#>   <chr> <chr>
#> 1 col1  2017 
#> 2 col2  2018
name_df
#> # A tibble: 4 x 3
#>   name  key   value
#>   <chr> <chr> <chr>
#> 1 dog   col1  10   
#> 2 cat   col1  30   
#> 3 dog   col2  20   
#> 4 cat   col2  50
month_df
#> # A tibble: 2 x 3
#>   key   month type 
#>   <chr> <chr> <chr>
#> 1 col1  June  New  
#> 2 col2  July  Old

Тогдаобъединить все назад по ключу (также можно использовать purrr::reduce, так как все объединения находятся в одном столбце)

yrs_df %>%
  inner_join(month_df, by = "key") %>%
  inner_join(name_df, by = "key")
#> # A tibble: 4 x 6
#>   key   year  month type  name  value
#>   <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 col1  2017  June  New   dog   10   
#> 2 col1  2017  June  New   cat   30   
#> 3 col2  2018  July  Old   dog   20   
#> 4 col2  2018  July  Old   cat   50

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

...