R: распространение data.frame / tibble с общими ключами и отсутствующими данными - PullRequest
1 голос
/ 07 мая 2020

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

Моя таблица заполнена данными трех женщин. Всего существует 5 категорий, и в целом каждая наполнена ценностью. Но некоторые данные о женщинах отсутствуют, что приводит к отсутствию всей строки - обратите внимание, что Jane пропускает информацию о weight.

a = data.frame(categories = c("name", "sex", "age", "weight", "high", 
                              "name", "sex", "age", "high", 
                              "name", "sex", "age", "weight", "high"),
               values = c("Emma", "female", "32", "72", "175",
                          "Jane", "female", "28", "165",
                          "Emma", "female", "42", "63", "170")) 

   categories values
1        name   Emma
2         sex   female
3         age     32
4      weight     72
5        high    175
6        name   Jane
7         sex female
8         age     28
9        high    165
10       name   Emma
11        sex female
12        age     42
13     weight     63
14       high    170

Я бы хотел получить из categories - столбцов и из values - строк. Но есть две основные проблемы:

1) ключи являются общими - две Эммы (поэтому я не могу использовать spread или reshape)

2) некоторые категории могут отсутствовать - как в случай веса Джейн (поэтому я не могу использовать pivot или split)

В конце я хотел бы изменить форму данных, чтобы получить такую ​​таблицу:

     name  sex    age  weight  high
     Emma  female 32   72      175
     Jane  female 28   NA      165
     Emma  female 42   63      170

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Предполагая, что 'name' всегда присутствует для каждой записи, мы можем создать столбец идентификатора и изменить его форму, используя pivot_wider.

library(dplyr)

a %>%
  group_by(grp = cumsum(categories == 'name')) %>%
  tidyr::pivot_wider(names_from = categories, values_from = values) %>%
  ungroup %>%
  select(-grp)

#  name  sex    age   weight high 
#  <chr> <chr>  <chr> <chr>  <chr>
#1 Emma  female 32    72     175  
#2 Jane  female 28    NA     165  
#3 Emma  female 42    63     170  

Тот же лог c в data.table:

library(data.table)
dcast(setDT(a), cumsum(categories == 'name')~categories, value.var = 'values')
0 голосов
/ 07 мая 2020

Предполагая, что все записи начинаются с name и поигрались в базовом R с magrittr для чистоты:

library(magrittr)
split(a, cumsum(a$categories == "name")) %>% 
  lapply(function(x) setNames(x[[2L]], x[[1L]])[unique(a$categories)]) %>% 
  do.call(rbind, .) %>% 
  data.frame()

  name    sex age weight high
1 Emma female  32     72  175
2 Jane female  28   <NA>  165
3 Emma female  42     63  170

Аналогично игра с data.table:

library(data.table)
split(a, cumsum(a$categories == "name")) %>% 
  lapply(transpose, make.names = "categories") %>% 
  rbindlist(fill = TRUE)
...