Выкладывайте и объединяйте списки неравных размеров с помощью dplyr - PullRequest
0 голосов
/ 06 ноября 2018

Мне интересно сделать довольно сложное объединение, и я не смог найти ответ. Вот пример набора данных:

dat2 <- data.frame(age = c(2,2), id = c("T1", "T2"), Height = c(1.1,1.2), Number = c(1,1), node_age = c(0, 0))
dat3 <- data.frame(age = c(3,3,3,3), id = c("T1", "T1", "T2", "T2"), Height = c(1.1,2.2, 1.2, 2.3), Number = c(1,2,1,2), node_age = c(1,0,1,0))
dat4 <- data.frame(age = c(4,4,4,4,4,4), id = c("T1", "T1", "T1", "T2", "T2", "T2"), Height = c(1.1,2.2,3.3,1.2, 2.3,3.4 ), Number = c(1,2,3,1,2,3), node_age = c(2,1,0,2,1,0))
dat_list <- list(dat2, dat3, dat4)

Я бы хотел взять этот список и объединить все вместе, чтобы результат выглядел примерно так:

$`T1`
  id Height Number_2 node_age_2 Number_3 node_age_3 Number_4 node_age_4
1 T1    1.1        1          0        1          1        1          2
2 T1    2.2       NA         NA        2          0        2          1
3 T1    3.3       NA         NA       NA         NA        3          0

$T2
  id Height Number_2 node_age_2 Number_3 node_age_3 Number_4 node_age_4
4 T2    1.2        1          0        1          1        1          2
5 T2    2.3       NA         NA        2          0        2          1
6 T2    3.4       NA         NA       NA         NA        3          0

Где вывод представляет собой список списков по id, а «Number» и «node_age» повторяются как функции «age».

Я достиг определенного прогресса в сборе, объединении и распространении. Но я чувствую, что неэффективно bind_rows списка, затем распространять, а затем объединить обратно в список. Может я тут не прав?

Мои настоящие данные - большой список (115 элементов). Когда я связываю список с моим списком, я получаю 233561 замечание. Поэтому у меня есть много идентификаторов, а node_age идет до 115, поэтому я стремлюсь к структурам списков.

Заранее спасибо.

1 Ответ

0 голосов
/ 06 ноября 2018

Мы можем связать строки, затем split по 'id' и dcast в 'широкий' формат

library(tidyverse)
library(data.table)
dat_list %>%
   bind_rows %>% 
   split(.$id) %>% 
   map(~  dcast(as.data.table(.x), id + Height ~ age, 
              value.var = c( 'Number', 'node_age')))
#$T1
#   id Height Number_2 Number_3 Number_4 node_age_2 node_age_3 node_age_4
#1: T1    1.1        1        1        1          0          1          2
#2: T1    2.2       NA        2        2         NA          0          1
#3: T1    3.3       NA       NA        3         NA         NA          0

#$T2
#   id Height Number_2 Number_3 Number_4 node_age_2 node_age_3 node_age_4
#1: T2    1.2        1        1        1          0          1          2
#2: T2    2.3       NA        2        2         NA          0          1
#3: T2    3.4       NA       NA        3         NA         NA          0

Или мы используем gather/spread вместо dcast

dat_list %>% 
   bind_rows %>%
   split(.$id) %>%
   map(~ .x  %>% 
            gather(key, val, Number:node_age) %>%
            unite(keyage, key, age) %>%
            spread(keyage, val))
#$T1
#  id Height node_age_2 node_age_3 node_age_4 Number_2 Number_3 Number_4
#1 T1    1.1          0          1          2        1        1        1
#2 T1    2.2         NA          0          1       NA        2        2
#3 T1    3.3         NA         NA          0       NA       NA        3

#$T2
#  id Height node_age_2 node_age_3 node_age_4 Number_2 Number_3 Number_4
#1 T2    1.2          0          1          2        1        1        1
#2 T2    2.3         NA          0          1       NA        2        2
#3 T2    3.4         NA         NA          0       NA       NA        3

Если нам нужны столбцы в определенном order, создайте «ключ» в виде factor столбцов с levels, указанным в этом порядке, чтобы изменить order в spread

dat_list %>% 
    bind_rows %>%
    split(.$id) %>%
    map(~ .x  %>% 
             gather(key, val, Number:node_age) %>%
             group_by(key) %>%
             mutate(rn = row_number())  %>%
             ungroup %>% 
             arrange(rn) %>%
             unite(keyage, key, age) %>%
             mutate(keyage = factor(keyage, levels = unique(keyage))) %>% 
             select(-rn) %>%
             spread(keyage, val))
#$T1
# A tibble: 3 x 8
#  id    Height Number_2 node_age_2 Number_3 node_age_3 Number_4 node_age_4
#  <fct>  <dbl>    <dbl>      <dbl>    <dbl>      <dbl>    <dbl>      <dbl>
#1 T1       1.1        1          0        1          1        1          2
#2 T1       2.2       NA         NA        2          0        2          1
#3 T1       3.3       NA         NA       NA         NA        3          0

#$T2
# A tibble: 3 x 8
#  id    Height Number_2 node_age_2 Number_3 node_age_3 Number_4 node_age_4
#  <fct>  <dbl>    <dbl>      <dbl>    <dbl>      <dbl>    <dbl>      <dbl>
#1 T2       1.2        1          0        1          1        1          2
#2 T2       2.3       NA         NA        2          0        2          1
#3 T2       3.4       NA         NA       NA         NA        3          0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...