简体   繁体   English

从列表中提取元素以创建矩阵

[英]Extracting elements from a list to create a matrix

I have a list of countries with lists inside each one of them.我有一份国家名单,每个国家都有名单。

Just to give you an example of a list object for one country with lists for two countries ( df_DOTS ):只是为您提供一个list object 的示例,其中一个国家/地区的列表包含两个国家/地区( df_DOTS ):

df_DOTS <- list(BR = structure(list(`@FREQ` = "M", `@REF_AREA` = "AU", `@INDICATOR` = "TXG_FOB_USD", 
    `@COUNTERPART_AREA` = "BR", `@UNIT_MULT` = "6", `@TIME_FORMAT` = "P1M", 
    Obs = list(structure(list(`@TIME_PERIOD` = c("2019-07", "2019-08", 
    "2019-09"), `@OBS_VALUE` = c("55.687747", "36.076581", "57.764474"
    )), class = "data.frame", row.names = c(NA, 3L)))), row.names = 2L, class = "data.frame"), 
    US = structure(list(`@FREQ` = "M", `@REF_AREA` = "AU", `@INDICATOR` = "TXG_FOB_USD", 
        `@COUNTERPART_AREA` = "US", `@UNIT_MULT` = "6", `@TIME_FORMAT` = "P1M", 
        Obs = list(structure(list(`@TIME_PERIOD` = c("2019-07", 
        "2019-08", "2019-09"), `@OBS_VALUE` = c("876.025841", 
        "872.02118", "787.272851")), class = "data.frame", row.names = c(NA, 
        3L)))), row.names = 1L, class = "data.frame"))

I can reach the matrix ( matrix_DOTS ) I am looking for using these lines of code:我可以使用这些代码行到达我正在寻找的矩阵( matrix_DOTS ):

library(dplyr)
library(rlist)
library(magrittr)

BR <- df_DOTS[["BR"]][["Obs"]] %>%
  list.select(.$`@OBS_VALUE`) %>%
  unlist() %>%
  sapply(function(x) as.numeric(as.character(x))) %>%
  mean()

US <- df_DOTS[["US"]][["Obs"]] %>%
  list.select(.$`@OBS_VALUE`) %>%
  unlist() %>%
  sapply(function(x) as.numeric(as.character(x))) %>%
  mean()

matrix_DOTS <- matrix(c(BR, US), nrow = 1, dimnames = list(c("AU"), c("BR", "US")))

Since I have a list of several countries with lists of other several countries inside them, I am looking for a more practical way of achieving matrix_DOTS .由于我有几个国家的列表,其中包含其他几个国家的列表,我正在寻找一种更实用的方法来实现matrix_DOTS Any help is highly appreciated!非常感谢任何帮助!

PS: This is the dput for the final matrix in this example: PS:这是此示例中最终矩阵的dput

matrix_DOTS <- structure(c(49.842934, 845.106624), .Dim = 1:2, .Dimnames = list(
    "AU", c("BR", "US")))

EDIT编辑

This is the procedure to obtain df_DOTS :这是获取df_DOTS的过程:

library(IMFData)

databaseID <- "DOT"
startdate = "2019-07-01"
enddate = "2019-09-01"
checkquery = FALSE

queryfilter <- list(CL_FREQ = "M", CL_AREA_DOT = "AU",
                    CL_INDICATOR_DOT = "TXG_FOB_USD",
                    CL_COUNTERPART_AREA_DOT = c("BR", "US"))
df_DOTS <- CompactDataMethod(databaseID, queryfilter, startdate, enddate, checkquery) %>%
  split(.$`@COUNTERPART_AREA`) 

Just add tidy = TRUE to the CompactDataMethod call:只需将tidy = TRUE添加到CompactDataMethod调用中:

library(IMFData)

databaseID <- "DOT"
startdate = "2019-07-01"
enddate = "2019-09-01"
checkquery = FALSE

queryfilter <- list(CL_FREQ = "M", CL_AREA_DOT = "AU",
                    CL_INDICATOR_DOT = "TXG_FOB_USD",
                    CL_COUNTERPART_AREA_DOT = c("BR", "US"))
df_DOTS <- CompactDataMethod(databaseID,
                             queryfilter,
                             startdate,
                             enddate,
                             checkquery,
                             tidy = TRUE)



df_DOTS
  @TIME_PERIOD @OBS_VALUE @FREQ @REF_AREA  @INDICATOR @COUNTERPART_AREA @UNIT_MULT @TIME_FORMAT
1      2019-07 876.025841     M        AU TXG_FOB_USD                US          6          P1M
2      2019-08  872.02118     M        AU TXG_FOB_USD                US          6          P1M
3      2019-09 787.272851     M        AU TXG_FOB_USD                US          6          P1M
4      2019-07  55.687747     M        AU TXG_FOB_USD                BR          6          P1M
5      2019-08  36.076581     M        AU TXG_FOB_USD                BR          6          P1M
6      2019-09  57.764474     M        AU TXG_FOB_USD                BR          6          P1M

you just need one group_by(@COUNTERPART_AREA) %>% summarise(mean = mean(@OBS_VALUE)) :你只需要一个group_by(@COUNTERPART_AREA) %>% summarise(mean = mean(@OBS_VALUE))

library(tidyverse)
df_DOTS %>%
  group_by(`@COUNTERPART_AREA`, `@REF_AREA`) %>%
  summarise(mean = mean(as.numeric(`@OBS_VALUE`))) %>%
  spread( `@COUNTERPART_AREA`, mean) 
#output
  `@REF_AREA`    BR    US
  <chr>       <dbl> <dbl>
1 AU           49.8  845.
  

Or if you insist on a matrix或者,如果您坚持使用矩阵

df_DOTS %>%
  group_by(`@COUNTERPART_AREA`, `@REF_AREA`) %>%
  summarise(mean = mean(as.numeric(`@OBS_VALUE`))) %>%
  spread( `@COUNTERPART_AREA`, mean) %>%
  column_to_rownames("@REF_AREA") %>%
  as.matrix
#output
         BR       US
AU 49.84293 845.1066

From the input data, we could loop over with map , pluck the elements that is needed, convert to numeric , get the mean , and convert to a two column tibble with enframe从输入数据中,我们可以使用map循环,提取需要的元素,转换为numeric ,获取mean ,然后转换为enframe pluck两列tibble

library(purrr)
library(tidyr)
map(df_DOTS, ~ .x %>% 
       pluck("Obs", 1, "@OBS_VALUE") %>%
        as.numeric %>%
        mean) %>%
   enframe %>%
   unnest(c(value))
# A tibble: 2 x 2
#   name  value
#  <chr> <dbl>
#1 BR     49.8
#2 US    845. 

Another option would be like this:另一种选择是这样的:

tmp <- df_DOTS %>% 
  as_tibble() %>% 
  summarise(across(everything(), ~mean(as.numeric(.x$Obs[[1]]$`@OBS_VALUE`))))
tmp
# # A tibble: 1 x 2
#       BR    US
#     <dbl> <dbl>
#   1  49.8  845.  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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