【问题标题】:Nested Json with Different Attribute Names in RR中具有不同属性名称的嵌套Json
【发布时间】:2021-01-29 22:41:56
【问题描述】:

我正在使用 Kaggle Star Trek Scripts 数据集,但我正在努力将 json 转换为 R 中的数据帧。理想情况下,我会将其转换为带有剧集索引列的长格式数据集和字符,它们的行位于单独的行上。我确实找到了this answer,但它不在 R 中。

目前 json 看起来像下面的照片。对不起,这不是一个完整的例子,但我也在下面放了一个小的模拟版本。如果您愿意,您可以自己从here 下载数据。

当前 JSON 视图

模拟示例

  "ENT": {
    "episode_0": {
      "KLAANG": {
        "\"Pungghap! Pung ghap!\"": {},
        "\"DujDajHegh!\"": {}
      }
    },
    "eipsode_1": {
      "ARCHER": {
        "\"Warpme!\"": {},
        "\"Toboldly go!\"": {}
      }
    }
  }
}

我遇到的问题是第二级,episodes,是单独编号的。因此,我按属性名称进行展平的常规技巧包不起作用。我不确定如何循环遍历关卡而不是属性名称。

理想情况下,我想要一个长格式的数据集,如下所示:

Series  Episode     Character   Lines
ENT     episode_0   KLAANG      Pung ghap! Pung ghap!
ENT     episode_0   KLAANG      DujDaj Hegh!
ENT     episode_1   ARCHER      Warp me!
ENT     episode_1   ARCHER      To boldly go!

我的当前代码如下所示,这是我通常开始使用的代码,但显然无法正常工作或远远不够。

your_df <- result[["ENT"]] %>%
  purrr::flatten() %>%
  map_if(is_list, as_tibble) %>%
  map_if(is_tibble, list) %>%
  bind_cols()

我也尝试过使用stack()map_dfr(),但没有成功。因此,亲爱的读者,我再次谦虚地向您寻求专业知识。 Json 是我存在的祸根。我很难将其他答案应用于我的情况,因此我可以逆向工程和学习的任何建议或示例都非常感谢。

如果可能的话,也很乐意澄清或扩展任何事情。

-杰克

【问题讨论】:

    标签: r json purrr jsonlite rjson


    【解决方案1】:

    因此,感谢 Michael 在这条名为 How to flatten a list of lists? 的踏板上的回答,所以我能够暴力破解它,所以向他们大声喊叫。

    该函数允许我将 JSON 转换为列表列表。

     flattenlist <- function(x){  
      morelists <- sapply(x, function(xprime) class(xprime)[1]=="list")
      out <- c(x[!morelists], unlist(x[morelists], recursive=FALSE))
      if(sum(morelists)){ 
        Recall(out)
      }else{
        return(out)
      }
    }
    

    因此,综上所述,我最终得到了以下解决方案。供您娱乐的注释。

    library(jsonlite)
    library(tidyverse)
    library(dplyr)
    library(data.table)
    library(rjson)
    
    result <- fromJSON(file = "C:/Users/jacob/Downloads/all_series_lines.json")
    
    # Mike's function to get to a list of lists
    flattenlist <- function(x){  
      morelists <- sapply(x, function(xprime) class(xprime)[1]=="list")
      out <- c(x[!morelists], unlist(x[morelists], recursive=FALSE))
      if(sum(morelists)){ 
        Recall(out)
      }else{
        return(out)
      }
    }
    
    # Mike's function applied
    final<-as.data.frame(do.call("rbind", flattenlist(result)))
    
    # Turn all the lists into a master data frame and ensure the index becomes a column I can separate later for context.
    final <- cbind(Index_Name = rownames(final), final)
    rownames(final) <- 1:nrow(final)
    
    # So the output takes the final elements at the end of the JSON and makes those the variables in a dataframe so I need to force it back to a long form dataset.
    final2<-gather(final,"key","value",-Index_Name)
    
    # I separate each element of index name into my three mapping variables; Series,Episode and Character. I can also keep the original column names from above as script line id
    final2$Episode<-gsub(".*\\.(.*)\\..*", "\\1", final2$Index_Name)
    final2$Series<-substr(final2$Index_Name, start = 1, stop = 3)
    final2$Character<-sub('.*\\.'," ", final2$newColName)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      • 1970-01-01
      • 2021-11-08
      • 2016-08-06
      • 1970-01-01
      相关资源
      最近更新 更多