简体   繁体   中英

Creating multiple Dataframes from a multidimensional array of matrices

I have a huge number of matrices (over 50) included in a single array. Each of my matrices represents a year (1951,1952, and so on). Each matrix contains observations of 4 plants at 80 locations. Consequently each matrix has 4 columns and 80 rows.

I want to rearrange my data into 4 dataframes. One Dataframe for each plant, meaning the dimensions of my array (the different years) become my colnames and the different locations become my rownames.

1951

    10  12 13  24
2   NA  NA NA 288
3  114 139 NA 287
4  104 128 NA 285
5  105 128 NA 289
6  107 123 NA 282
7  112 121 NA 289
8  110 130 NA 287
9  112 128 NA 290
10 107 125 NA 284
.  .   .   .  .
.  .   .   .  .

1952

    10  12 13  24
2   45  34 345 45
3  345 139 NA 287
4  104 128 345 285
5  105 128 NA 289
6  137 123 NA 282
7  112 141 123 239
8  110 130 NA 287
9  112 128 123 230
10 307 125 NA 284
.  .   .   .  .
.  .   .   .  .

Is there any quick way to do this? This would be of great advantage for my following calculations!

Suppose we have the 9x4x2 array a shown reproducibly in the Note at the end. Then we can use apply to get a list of data frames from it. Replace 2 with 1 or 3 to get other variations.

apply(a, 2, as.data.frame)

giving:

$`10`
   1951 1952
2    45   45
3   345  345
4   104  104
5   105  105
6   137  137
7   112  112
8   110  110
9   112  112
10  307  307

$`12`
   1951 1952
2    34   34
3   139  139
4   128  128
5   128  128
6   123  123
7   141  141
8   130  130
9   128  128
10  125  125

$`13`
   1951 1952
2   345  345
3    NA   NA
4   345  345
5    NA   NA
6    NA   NA
7   123  123
8    NA   NA
9   123  123
10   NA   NA

$`14`
   1951 1952
2    45   45
3   287  287
4   285  285
5   289  289
6   282  282
7   239  239
8   287  287
9   230  230
10  284  284

Note

a <- array(data = c(45L, 345L, 104L, 105L, 137L, 112L, 110L, 112L, 307L, 34L, 139L, 
  128L, 128L, 123L, 141L, 130L, 128L, 125L, 345L, NA, 345L, NA, 
  NA, 123L, NA, 123L, NA, 45L, 287L, 285L, 289L, 282L, 239L, 287L, 
  230L, 284L, 45L, 345L, 104L, 105L, 137L, 112L, 110L, 112L, 307L, 
  34L, 139L, 128L, 128L, 123L, 141L, 130L, 128L, 125L, 345L, NA, 
  345L, NA, NA, 123L, NA, 123L, NA, 45L, 287L, 285L, 289L, 282L, 
  239L, 287L, 230L, 284L), 
dim = c(9, 4, 2),
dimnames = list(c("2", "3", "4", "5", "6", "7", "8", "9", "10"), c("10", 
  "12", "13", "14"), c("1951", "1952"))
)

I made some small example data called years_dfs for the thing you are trying to achieve. It should also work if you use a list of matrices instead of data frames.

library(tidyverse)
years <- 1951:1953
year_dfs <- list(data.frame(a = 1:5, b = 6:10), 
                 data.frame(a = 11:15, b = 16:20), 
                 data.frame(a = 21:25, b = 26:30)) %>% 
  `names<-`(years)
year_dfs
$`1951`
  a  b
1 1  6
2 2  7
3 3  8
4 4  9
5 5 10

$`1952`
   a  b
1 11 16
2 12 17
3 13 18
4 14 19
5 15 20

$`1953`
   a  b
1 21 26
2 22 27
3 23 28
4 24 29
5 25 30

lapply(1:ncol(year_dfs[[1]]), function(plant)
  lapply(1:length(year_dfs), function(year)
    year_dfs[[year]][,plant]) %>% 
    as.data.frame %>% 
    `colnames<-`(years)
  ) %>% `names<-`(colnames(year_dfs[[1]]))
$a
  1951 1952 1953
1    1   11   21
2    2   12   22
3    3   13   23
4    4   14   24
5    5   15   25

$b
  1951 1952 1953
1    6   16   26
2    7   17   27
3    8   18   28
4    9   19   29
5   10   20   30

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM