Элегантный, функциональный способ извлечения данных из этого вложенного списка R - PullRequest
1 голос
/ 07 марта 2020

Учитывая следующий объект конфигурации:

sourceClust = list(
  clust1 = list(
    prop = 0.25,
    Dim1 = list(
      mean = 2,
      sd   = 0.05
    ) ,
    Dim2 = list(
     mean = 3,
     sd = .1
    )
  ),
  clust2 = list(
    Dim1 = list(
      mean = 4,
      sd   = .1
    ),
    Dim2 = list(
      mean = 3,
      sd = 0.2
    ),
    prop = 0.75
  )
);

Существует ли элегантный, функциональный способ извлечения данных в следующем формате?

clusterMeans = data.frame(Dim1=c(2,4),Dim2=c(3,3));
clusterSD = data.frame(Dim1 = c(0.05,0.1), Dim2 = c(0.1,0.2));
clusterProp = c(0.25, 0.75);

Я понимаю, что вышеприведенное может быть выполняется с помощью некоторых вложенных циклов, но я пытаюсь выяснить, могу ли я использовать функциональное моделирование для выполнения sh этой задачи. Я ищу решение в базе R или с помощью библиотеки (Tidyverse это здорово).

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Вы можете сделать

order_df <- function(x) unlist(x)[order(names(unlist(x)))]
df <- as.data.frame(do.call(rbind, lapply(sourceClust, order_df)))
df
#>        Dim1.mean Dim1.sd Dim2.mean Dim2.sd prop
#> clust1         2    0.05         3     0.1 0.25
#> clust2         4    0.10         3     0.2 0.75

, а затем просто поднастроить столбцы:

clusterMeans <- df[grepl("mean", names(df))]
clusterSD    <- df[grepl("sd", names(df))]
clusterProp  <- df[[grep("prop", names(df))[1]]]

Или в форме канала, создав именованный список фреймов данных:

sourceClust %>% 
  lapply(function(x) unlist(x)[order(names(unlist(x)))]) %>%
  {do.call(rbind, .)} %>%
  as.data.frame() %>%
  {lapply(c("mean", "sd", "prop"), function(x) .[grep(x, names(.))])} %>%
  `names<-`(c("mean", "sd", "prop"))
># $mean
>#        Dim1.mean Dim2.mean
># clust1         2         3
># clust2         4         3
># 
># $sd
>#        Dim1.sd Dim2.sd
># clust1    0.05     0.1
># clust2    0.10     0.2
># 
># $prop
>#        prop
># clust1 0.25
># clust2 0.75
0 голосов
/ 07 марта 2020

Пакет purrr имеет некоторые вспомогательные функции, такие как map и pluck, которые могут помочь. Например,

clusterProp <- map_dbl(sourceClust, "prop")

и

map_dbl(sourceClust, ~pluck(., "Dim1", "sd"))

Вы также можете сделать

cols <- c("Dim1", "Dim2")
clusterMeans <- map(cols, function(col) map_dbl(sourceClust, ~pluck(., col, "mean"))) %>%
  set_names(cols) %>% as_tibble()
clusterSD  <- map(cols, function(col) map_dbl(sourceClust, ~pluck(., col, "sd"))) %>%
  set_names(cols) %>% as_tibble()

Но так как вы делаете такое большое изменение формы, это не совсем "элегантно".

...