【问题标题】:Need Help Extracting 4 Nested Lists into Data Frame需要帮助将 4 个嵌套列表提取到数据框中
【发布时间】:2018-07-26 01:26:03
【问题描述】:

有问题的数据是我转换为列表的 JSON 结果。数据如下所示:

data <- list(query_day = c('Monday'),
              requester = c('John'),
              detail =
                list(list(ID = 1, weight = 200),
                     list(ID = 2, weight = 300),
                     list(ID = 3, weight = 400,
                          detail2 = list(height = 6.5,
                                         gender = 'M',
                                         name = 'John')),
                     list(ID = 4, weight = 500),
                     list(ID = 5, weight = 600,
                          detail2 = list(height = 5.5,
                                         gender = 'F',
                                         name = 'Jane'))))

我有兴趣提取嵌套在“详细信息”中的数据。因为有些列表有细节 2,但有些没有。在尝试提取数据之前,我应用了以下代码

detail <- data[['detail']]
detail_2_cols <- detail[which(sapply(detail, length) == 2)]
detail_3_cols <- detail[which(sapply(detail, length) == 3)]

然后我尝试了两种方法都不管用。

第一种方法

result_data.frame <- data.frame(t(sapply(detail_2_cols,c)))

这将产生一个包含 ID 和权重列的数据框(根据 class())。但是这些列仍然是一个列表,这使得 mean() 之类的功能无法使用。

Dataframe. But columns are lists

第二种方法

result_do.call <-do.call(rbind,lapply(detail_2_cols,data.frame))

这适用于示例:结果是数据框,每列不是列表。

最大的问题是,当我将相同的代码应用于数据集时,我得到了

错误(函数(...,row.names = NULL,check.rows = FALSE,check.names = TRUE,:参数暗示不同的行数:1、0 p>

我认为不同的列应该不是问题,因为我在将它们转换为数据框之前将它们分开。

我希望输出具有 ID 和 weight 列,它们不是第一种方法的结果列表。

Expected Output Dataframe

先谢谢你了。

【问题讨论】:

  • 是的,我刚刚添加了图片。
  • 那么您有兴趣使用length 2 从“详细信息”中提取数据吗?此外,您需要向我们提供代码不起作用的数据,以验证我们提供的答案是否适用于您的真实数据,而不仅仅是您共享的样本。

标签: r


【解决方案1】:

这是检查数据结构的另一种快速而肮脏的方法:

library(dplyr)
library(jsonlite)
library(tidyverse)

> z <- data %>% toJSON() %>% fromJSON()
> z$detail
  ID weight detail2.height detail2.gender detail2.name
1  1    200           NULL           NULL         NULL
2  2    300           NULL           NULL         NULL
3  3    400            6.5              M         John
4  4    500           NULL           NULL         NULL
5  5    600            5.5              F         Jane

> z.df <- as.data.frame(z$detail)

> z$detail$detail2
  height gender name
1   NULL   NULL NULL
2   NULL   NULL NULL
3    6.5      M John
4   NULL   NULL NULL
5    5.5      F Jane

这里是你如何让它像一个数据框一样工作(杂乱无章但有效):

> zzz <- read.table(textConnection(captureOutput(print(z.df))), 
    stringsAsFactors=FALSE)

> zzz
  ID weight detail2.height detail2.gender detail2.name
1  1    200           NULL           NULL         NULL
2  2    300           NULL           NULL         NULL
3  3    400            6.5              M         John
4  4    500           NULL           NULL         NULL
5  5    600            5.5              F         Jane

> str(zzz)
'data.frame':   5 obs. of  5 variables:
 $ ID            : int  1 2 3 4 5
 $ weight        : int  200 300 400 500 600
 $ detail2.height: chr  "NULL" "NULL" "6.5" "NULL" ...
 $ detail2.gender: chr  "NULL" "NULL" "M" "NULL" ...
 $ detail2.name  : chr  "NULL" "NULL" "John" "NULL" ...

现在您可以在您发布的图片中准确找到所需的数据框:

> final.df <- zzz %>% replace(.=="NULL", NA) %>% 
    filter(!complete.cases(.)) %>% select(ID,weight) %>% 
    as.tibble()

> final.df
# A tibble: 3 x 2
     ID weight
  <int>  <int>
1     1    200
2     2    300
3     4    500

【讨论】:

    【解决方案2】:

    为了快速而肮脏的修复,您可以尝试rlist library

    library(rlist)
    
    rlist::list.flatten(data) %>% dplyr::bind_rows()
    

    你会得到一个小标题,你可以在上面申请dplyr::select(contains("detail"))来拉出你想要的列。

    【讨论】:

      猜你喜欢
      • 2021-09-27
      • 2021-11-20
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-10
      • 2013-02-22
      • 1970-01-01
      相关资源
      最近更新 更多