使用`purrr`将列表列表中的数据提取到自己的`data.frame`中

daR*_*ght 1 r list dplyr purrr

代表性样本数据(清单清单):

l <- list(structure(list(a = -1.54676469632688, b = "s", c = "T", 
d = structure(list(id = 5L, label = "Utah", link = "Asia/Anadyr", 
    score = -0.21104594634643), .Names = c("id", "label", 
"link", "score")), e = 49.1279871269422), .Names = c("a", 
"b", "c", "d", "e")), structure(list(a = -0.934821052832427, 
b = "k", c = "T", d = list(structure(list(id = 8L, label = "South Carolina", 
    link = "Pacific/Wallis", score = 0.526540892113734, externalId = -6.74354377676955), .Names = c("id", 
"label", "link", "score", "externalId")), structure(list(
    id = 9L, label = "Nebraska", link = "America/Scoresbysund", 
    score = 0.250895465294041, externalId = 16.4257470807879), .Names = c("id", 
"label", "link", "score", "externalId"))), e = 52.3161400117052), .Names = c("a", 
"b", "c", "d", "e")), structure(list(a = -0.27261485993069, b = "f", 
c = "P", d = list(structure(list(id = 8L, label = "Georgia", 
    link = "America/Nome", score = 0.526494135483816, externalId = 7.91583574935589), .Names = c("id", 
"label", "link", "score", "externalId")), structure(list(
    id = 2L, label = "Washington", link = "America/Shiprock", 
    score = -0.555186440792989, externalId = 15.0686663219837), .Names = c("id", 
"label", "link", "score", "externalId")), structure(list(
    id = 6L, label = "North Dakota", link = "Universal", 
    score = 1.03168296038975), .Names = c("id", "label", 
"link", "score")), structure(list(id = 1L, label = "New Hampshire", 
    link = "America/Cordoba", score = 1.21582056168681, externalId = 9.7276418869132), .Names = c("id", 
"label", "link", "score", "externalId")), structure(list(
    id = 1L, label = "Alaska", link = "Asia/Istanbul", score = -0.23183264861979), .Names = c("id", 
"label", "link", "score")), structure(list(id = 4L, label = "Pennsylvania", 
    link = "Africa/Dar_es_Salaam", score = 0.590245339334121), .Names = c("id", 
"label", "link", "score"))), e = 132.1153538536), .Names = c("a", 
"b", "c", "d", "e")), structure(list(a = 0.202685974077313, b = "x", 
c = "O", d = structure(list(id = 3L, label = "Delaware", 
    link = "Asia/Samarkand", score = 0.695577130634724, externalId = 15.2364820698193), .Names = c("id", 
"label", "link", "score", "externalId")), e = 97.9908914452971), .Names = c("a", 
"b", "c", "d", "e")), structure(list(a = -0.396243444741009, 
b = "z", c = "P", d = list(structure(list(id = 4L, label = "North Dakota", 
    link = "America/Tortola", score = 1.03060272795705, externalId = -7.21666936522344), .Names = c("id", 
"label", "link", "score", "externalId")), structure(list(
    id = 9L, label = "Nebraska", link = "America/Ojinaga", 
    score = -1.11397997280413, externalId = -8.45145052697411), .Names = c("id", 
"label", "link", "score", "externalId"))), e = 123.597945533926), .Names = c("a", 
"b", "c", "d", "e")))
Run Code Online (Sandbox Code Playgroud)

凭借JSON数据下载,我有一个列表列表.

该列表有176个元素,每个元素有33个嵌套元素,其中一些也是不同长度的列表.

我有兴趣分析特定嵌套列表中包含的数据,其中176个中的每一个的长度为〜150,其中有4个或5个元素 - 有些有4个,有些有5个.我试图提取这个嵌套感兴趣的列表并将其转换data.frame为能够执行某些分析.

在上面的代表性示例数据中,我d对5个元素中的每个元素的嵌套列表感兴趣l.data.frame因此,所需的内容如下:

id           label            link       score  externalId
 5            Utah     Asia/Anadyr  -0.2110459          NA
 8  South Carolina  Pacific/Wallis   0.5265409   -6.743544
 .
 .
Run Code Online (Sandbox Code Playgroud)

我一直试图使用purrr似乎有一个明智和一致的流程来处理列表中的数据,但我遇到的错误,我无法完全理解的原因 - 很可能是我没有正确理解命令/逻辑purrr或列表(可能两者).这是我一直尝试的代码,但抛出相关的错误:

df <- map_df(l, "d", ~as.data.frame(.))
Error: incompatible sizes (5 != 4)
Run Code Online (Sandbox Code Playgroud)

我认为这与d每个组件的不同长度有关,或者可能是不同的包含数据(有时4个元素有时为5)或者我在这里使用的函数可能是错误的 - 实际上我并不完全确定.

我通过使用for循环解决了这个问题,我知道这是低效的,因此我的问题就在这里.

这是我目前使用的for循环:

df <- data.frame(id = integer(), label = character(), score = numeric(), externalId = numeric())
for(i in seq_along(l)){
    df_temp <- l[[i]][[4]] %>% map_df(~as.data.frame(.))
    df <- rbind(df, df_temp)
}
Run Code Online (Sandbox Code Playgroud)

最好的一些帮助purrr- 或者某些版本apply仍然优于我的for-loop - 将非常感激.此外,如果有上述资源,我想了解而不是只找到正确的代码.

aos*_*ith 6

您可以分三步完成此操作,首先拉出d,然后绑定每个元素中的行d,然后将所有内容绑定到单个对象中.

我用bind_rowsdplyr的范围内,列表行结合. map_df做最后一行绑定.

library(purrr)
library(dplyr)

l %>%
    map("d") %>%
    map_df(bind_rows)
Run Code Online (Sandbox Code Playgroud)

这也是等价的:

map_df(l, ~bind_rows(.x[["d"]] ) )
Run Code Online (Sandbox Code Playgroud)

结果如下:

# A tibble: 12 x 5
      id          label                 link      score externalId
   <int>          <chr>                <chr>      <dbl>      <dbl>
 1     5           Utah          Asia/Anadyr -0.2110459         NA
 2     8 South Carolina       Pacific/Wallis  0.5265409  -6.743544
 3     9       Nebraska America/Scoresbysund  0.2508955  16.425747
 4     8        Georgia         America/Nome  0.5264941   7.915836
 5     2     Washington     America/Shiprock -0.5551864  15.068666
 6     6   North Dakota            Universal  1.0316830         NA
 7     1  New Hampshire      America/Cordoba  1.2158206   9.727642
 8     1         Alaska        Asia/Istanbul -0.2318326         NA
 9     4   Pennsylvania Africa/Dar_es_Salaam  0.5902453         NA
10     3       Delaware       Asia/Samarkand  0.6955771  15.236482
11     4   North Dakota      America/Tortola  1.0306027  -7.216669
12     9       Nebraska      America/Ojinaga -1.1139800  -8.451451
Run Code Online (Sandbox Code Playgroud)