Как объединить имена при преобразовании вложенного списка во фрейм данных - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть вложенные списки с именами:

lst <- list(var1 = list(`0.1` = c(100, 10, 1, 0.1, 0.01), `0.2` = c(100, 
20, 4, 0.8, 0.16), `0.3` = c(100, 30, 9, 2.7, 0.81), `0.4` = c(100, 
40, 16, 6.4, 2.56), `0.5` = c(100, 50, 25, 12.5, 6.25), `0.6` = c(100, 
60, 36, 21.6, 12.96), `0.7` = c(100, 70, 49, 34.3, 24.01), `0.8` = c(100, 
80, 64, 51.2, 40.96), `0.9` = c(100, 90, 81, 72.9, 65.61)), var2 = list(
    `0.1` = c(10, 11, 11.1, 11.11, 11.111), `0.2` = c(10, 12, 
    12.4, 12.48, 12.496), `0.3` = c(10, 13, 13.9, 14.17, 14.251
    ), `0.4` = c(10, 14, 15.6, 16.24, 16.496), `0.5` = c(10, 
    15, 17.5, 18.75, 19.375), `0.6` = c(10, 16, 19.6, 21.76, 
    23.056), `0.7` = c(10, 17, 21.9, 25.33, 27.731), `0.8` = c(10, 
    18, 24.4, 29.52, 33.616), `0.9` = c(10, 19, 27.1, 34.39, 
    40.951)))

Я хочу преобразовать его во фрейм данных. Я мог бы сделать это с dplyr::bind_cols, но тогда мои имена частично потерялись:

# A tibble: 5 x 18
   `0.1`  `0.2`  `0.3`  `0.4`  `0.5` `0.6` `0.7` `0.8` `0.9` `0.11` `0.21` `0.31` `0.41` `0.51` `0.61` `0.71` `0.81`
   <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 100    100    100    100    100    100   100   100   100     10     10     10     10     10     10     10     10  
2  10     20     30.    40     50     60    70    80    90     11     12     13     14     15     16     17     18  
3   1      4      9.    16     25     36    49.   64    81     11.1   12.4   13.9   15.6   17.5   19.6   21.9   24.4
4   0.1    0.8    2.7    6.4   12.5   21.6  34.3  51.2  72.9   11.1   12.5   14.2   16.2   18.8   21.8   25.3   29.5
5   0.01   0.16   0.81   2.56   6.25  13.0  24.0  41.0  65.6   11.1   12.5   14.3   16.5   19.4   23.1   27.7   33.6
# ... with 1 more variable: `0.91` <dbl>

, в то время как я хотел бы создать информативные имена, объединяющие имена из двух уровней списка вместе. Таким образом, в результате вы получите:

# A tibble: 5 x 18
  var1_0.1 var1_0.2 var1_0.3 var1_0.4 var1_0.5 var1_0.6 var1_0.7 var1_0.8 var1_0.9 var2_0.1 var2_0.2 var2_0.3 var2_0.4
     <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1   100      100      100      100      100       100      100      100      100       10       10       10       10  
2    10       20       30.      40       50        60       70       80       90       11       12       13       14  
3     1        4        9.      16       25        36       49.      64       81       11.1     12.4     13.9     15.6
4     0.1      0.8      2.7      6.4     12.5      21.6     34.3     51.2     72.9     11.1     12.5     14.2     16.2
5     0.01     0.16     0.81     2.56     6.25     13.0     24.0     41.0     65.6     11.1     12.5     14.3     16.5
# ... with 5 more variables: var2_0.5 <dbl>, var2_0.6 <dbl>, var2_0.7 <dbl>, var2_0.8 <dbl>, var2_0.9 <dbl>

Как мне добиться этого наиболее эффективным способом?

Ответы [ 4 ]

2 голосов
/ 30 апреля 2020

Я не использовал dplyr , но data.table и rlist .

Это то, что вы хотели?

library(data.table)
library(rlist)

lst <- list(var1 = list(`0.1` = c(100, 10, 1, 0.1, 0.01), 
                        `0.2` = c(100, 20, 4, 0.8, 0.16), 
                        `0.3` = c(100, 30, 9, 2.7, 0.81), 
                        `0.4` = c(100, 40, 16, 6.4, 2.56), 
                        `0.5` = c(100, 50, 25, 12.5, 6.25), 
                        `0.6` = c(100, 60, 36, 21.6, 12.96), 
                        `0.7` = c(100, 70, 49, 34.3, 24.01), 
                        `0.8` = c(100, 80, 64, 51.2, 40.96), 
                        `0.9` = c(100, 90, 81, 72.9, 65.61)), 
            var2 = list(`0.1` = c(10, 11, 11.1, 11.11, 11.111), 
                        `0.2` = c(10, 12, 12.4, 12.48, 12.496), 
                        `0.3` = c(10, 13, 13.9, 14.17, 14.251), 
                        `0.4` = c(10, 14, 15.6, 16.24, 16.496), 
                        `0.5` = c(10, 15, 17.5, 18.75, 19.375), 
                        `0.6` = c(10, 16, 19.6, 21.76, 23.056), 
                        `0.7` = c(10, 17, 21.9, 25.33, 27.731), 
                        `0.8` = c(10, 18, 24.4, 29.52, 33.616), 
                        `0.9` = c(10, 19, 27.1, 34.39, 40.951)))


temp = lapply(lst, as.data.table)
final = rlist::list.cbind( temp )
final
#>    var1.0.1 var1.0.2 var1.0.3 var1.0.4 var1.0.5 var1.0.6 var1.0.7 var1.0.8
#> 1:    1e+02   100.00   100.00   100.00   100.00   100.00   100.00   100.00
#> 2:    1e+01    20.00    30.00    40.00    50.00    60.00    70.00    80.00
#> 3:    1e+00     4.00     9.00    16.00    25.00    36.00    49.00    64.00
#> 4:    1e-01     0.80     2.70     6.40    12.50    21.60    34.30    51.20
#> 5:    1e-02     0.16     0.81     2.56     6.25    12.96    24.01    40.96
#>    var1.0.9 var2.0.1 var2.0.2 var2.0.3 var2.0.4 var2.0.5 var2.0.6 var2.0.7
#> 1:   100.00   10.000   10.000   10.000   10.000   10.000   10.000   10.000
#> 2:    90.00   11.000   12.000   13.000   14.000   15.000   16.000   17.000
#> 3:    81.00   11.100   12.400   13.900   15.600   17.500   19.600   21.900
#> 4:    72.90   11.110   12.480   14.170   16.240   18.750   21.760   25.330
#> 5:    65.61   11.111   12.496   14.251   16.496   19.375   23.056   27.731
#>    var2.0.8 var2.0.9
#> 1:   10.000   10.000
#> 2:   18.000   19.000
#> 3:   24.400   27.100
#> 4:   29.520   34.390
#> 5:   33.616   40.951

Создано в 2020-04-30 пакетом prex (v0.3.0)

1 голос
/ 30 апреля 2020

Вы можете использовать dplyr::bind_cols для преобразования во фрейм данных (как вы уже упоминали), а затем изменить имена, используя базу R, повторяя имена первого уровня соответствующее количество раз:

df <- dplyr::bind_cols(lst)
names(df) <- paste(rep(names(lst), times = sapply(lst, length)), 
                   unlist(lapply(lst, names)), 
                   sep = '_')

Если вы знаете свой Имена внутренних уровней перед рукой становятся еще проще:

paste(rep(names(lst), each = 9), seq(0.1, 0.9, by = 0.1), sep = '_')
0 голосов
/ 30 апреля 2020

a data.table решение

library(data.table)

l <- lapply(seq_along(lst),function(x){
  tmp <- as.data.table(lst[[x]])
  names(tmp) <- paste0(names(lst)[x],"_",names(lst[[x]]))
  tmp
})

as.data.table(unlist(l,recursive = FALSE))
#>    var1_0.1 var1_0.2 var1_0.3 var1_0.4 var1_0.5 var1_0.6 var1_0.7 var1_0.8
#> 1:    1e+02   100.00   100.00   100.00   100.00   100.00   100.00   100.00
#> 2:    1e+01    20.00    30.00    40.00    50.00    60.00    70.00    80.00
#> 3:    1e+00     4.00     9.00    16.00    25.00    36.00    49.00    64.00
#> 4:    1e-01     0.80     2.70     6.40    12.50    21.60    34.30    51.20
#> 5:    1e-02     0.16     0.81     2.56     6.25    12.96    24.01    40.96
#>    var1_0.9 var2_0.1 var2_0.2 var2_0.3 var2_0.4 var2_0.5 var2_0.6 var2_0.7
#> 1:   100.00   10.000   10.000   10.000   10.000   10.000   10.000   10.000
#> 2:    90.00   11.000   12.000   13.000   14.000   15.000   16.000   17.000
#> 3:    81.00   11.100   12.400   13.900   15.600   17.500   19.600   21.900
#> 4:    72.90   11.110   12.480   14.170   16.240   18.750   21.760   25.330
#> 5:    65.61   11.111   12.496   14.251   16.496   19.375   23.056   27.731
#>    var2_0.8 var2_0.9
#> 1:   10.000   10.000
#> 2:   18.000   19.000
#> 3:   24.400   27.100
#> 4:   29.520   34.390
#> 5:   33.616   40.951

Создано в 2020-04-30 пакетом представительство (v0.3.0)

0 голосов
/ 30 апреля 2020

в Base-R

new_lst <- do.call(cbind,lapply(lst, function(x) do.call(cbind,x)))
colnames(new_lst) <- with(stack(lapply(lst, names)), paste(ind,values,sep="_"))

Еще один метод в Base-R (этот гораздо проще понять)

lst <- do.call(cbind,unlist(lst,recursive=F))
colnames(lst) <- lapply(colnames(lst), function(x) sub("\\.","_",x))

выход

> new_lst
     var1_0.1 var1_0.2 var1_0.3 var1_0.4 var1_0.5 var1_0.6 var1_0.7 var1_0.8 var1_0.9 var2_0.1 var2_0.2 var2_0.3 var2_0.4 var2_0.5 var2_0.6 var2_0.7 var2_0.8 var2_0.9
[1,]    1e+02   100.00   100.00   100.00   100.00   100.00   100.00   100.00   100.00   10.000   10.000   10.000   10.000   10.000   10.000   10.000   10.000   10.000
[2,]    1e+01    20.00    30.00    40.00    50.00    60.00    70.00    80.00    90.00   11.000   12.000   13.000   14.000   15.000   16.000   17.000   18.000   19.000
[3,]    1e+00     4.00     9.00    16.00    25.00    36.00    49.00    64.00    81.00   11.100   12.400   13.900   15.600   17.500   19.600   21.900   24.400   27.100
[4,]    1e-01     0.80     2.70     6.40    12.50    21.60    34.30    51.20    72.90   11.110   12.480   14.170   16.240   18.750   21.760   25.330   29.520   34.390
[5,]    1e-02     0.16     0.81     2.56     6.25    12.96    24.01    40.96    65.61   11.111   12.496   14.251   16.496   19.375   23.056   27.731   33.616   40.951
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...