Biorąc pod uwagę następujący obiekt konfiguracyjny:

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
  )
);

Czy istnieje elegancki, funkcjonalny sposób na wyodrębnienie danych w poniższym formacie?

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);

Rozumiem, że powyższe można wykonać z pewnymi zagnieżdżonymi pętli, ale próbuję zobaczyć, czy mogę użyć stylizacji funkcjonalnej, aby wykonać to zadanie. Szukam rozwiązania w bazie R lub za pomocą biblioteki (Tidyverse jest świetny).

1
Battlefrisk 7 marzec 2020, 00:01

2 odpowiedzi

Najlepsza odpowiedź

Możesz to zrobić

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

Następnie po prostu podzbiór kolumny:

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

Lub w formie rur, wytwarzając nazwę nazwę ramek danych:

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
1
Allan Cameron 6 marzec 2020, 22:26

Pakiet purrr ma jakieś funkcje pomocnicze, takie jak map i pluck, co może pomóc. Na przykład

clusterProp <- map_dbl(sourceClust, "prop")

I

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

Ty też możesz to zrobić

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()

Ale ponieważ robisz tak wiele rezygnacji, to nie jest dokładnie "elegancko".

-1
MrFlick 6 marzec 2020, 21:16