【问题标题】:Nested lists in R to JSON for Power BI用于 Power BI 的 R 到 JSON 中的嵌套列表
【发布时间】:2020-07-04 13:33:54
【问题描述】:

我在 R 中创建了一个数据集,其中包含 20 个变量的 800 个观察值,其中一些是向量(长度不同) 例如 观察 1:var1=1, var2="a", vec1=c("a", "b", "c"), vec2 = c(1,2,3) 观察2:var1=1, var2="a", vec1=c("a"), vec2 = c(1,2,3,4,5)

我尝试创建单个数据框,但它不喜欢不同长度的向量,因此当前数据存在为长度为 800 的多个向量(一个用于 var1,一个用于 var2 等)和多个长度列表800(包含vec1、vec2等)

将其组合成单个数据对象以使用嵌套列表的唯一方法是什么?

最终我需要输出为 JSON 以引入 Power BI,但我不知道如何组合现有元素来实现这一点。我尝试创建一个嵌套列表,然后创建 toJSON(),但这并不能解析为包含列的表(在 Power BI 中),而是每个列表项显示为需要扩展为 800 行的行。

非常感谢任何帮助!

【问题讨论】:

    标签: r json nested-lists


    【解决方案1】:

    据我了解,您目前有:

    vector_var1 <- c(1, 1)
    vector_var2 <- c("a", "a")
    list_vec1 <- list(c("a", "b", "c"), c("a"))
    list_vec2 <- list(c(1,2,3), c(1,2,3,4,5))
    

    您可以将其放入具有 列表列的数据框中:

    dat <- data.frame(
      var1 = vector_var1,
      var2 = vector_var2,
      vec1 = I(list_vec1),
      vec2 = I(list_vec2)
    )
    

    这给出了这个 JSON:

    jsonlite::toJSON(dat, pretty = TRUE)
    # [
    #   {
    #     "var1": 1,
    #     "var2": "a",
    #     "vec1": ["a", "b", "c"],
    #     "vec2": [1, 2, 3]
    #   },
    #   {
    #     "var1": 1,
    #     "var2": "a",
    #     "vec1": ["a"],
    #     "vec2": [1, 2, 3, 4, 5]
    #   }
    # ]
    

    这是你需要的吗?

    编辑

    根据 cmets 中的讨论,以下是如何使用 purrr::transpose 和 rlist::list.zip 获得所需结果:

    vector_var1 <- c(1, 1)
    vector_var2 <- c("a", "a")
    list_vec1 <- list(c("a", "b", "c"), c("a", "b", "c", "d", "e"))
    list_vec2 <- list(c(1,2,3), c(1,2,3,4,5))
    
    L1 <- purrr::transpose(list(list_vec1, list_vec2))
    L2 <- lapply(L1, function(vecs){
      do.call(rlist::list.zip, c(vecs, list(use.names=FALSE)))
    })
    
    dat <- data.frame(var1 = vector_var1, var2 = vector_var1, vec = I(L2))
    
    jsonlite::toJSON(dat, auto_unbox = TRUE)
    # [{"var1":1,"var2":1,"vec":[["a",1],["b",2],["c",3]]},{"var1":1,"var2":1,"vec":[["a",1],["b",2],["c",3],["d",4],["e",5]]}]
    

    【讨论】:

    • 太好了 - 非常感谢您的回答 - 稍后会尝试并让您知道!非常感谢。
    • 太好了,非常感谢 Stephane - 完全按照要求工作!唯一的事情是,我真正需要做的是将列表中每个向量的元素联系在一起,例如在观察 1 中,vec1[1] ("a") 和 vec2[1] (1) 是相关的,vec1 也是如此[2] ("b") 和 vec2[2] (2).. 所以我现在想知道是否有更好的方法可以构建数据,以便在 Power BI 中正确展开。
    • 我意识到我的示例第二次观察是不正确的,因为单个观察中每个向量的长度必须相等,所以 obsv 2, vec1 应该是 c("a", "b", "c" ,“d”,“e”)。道歉!
    • @esteebie 我不知道 Power BI,也不懂你的意思。像"vec": [["a",1], ["b",2], ["c",3]] 这样的东西合适吗?否则,你能显示你期望的输出吗?
    • 感谢 Stephane,这正是我所需要的,并设法通过在现有数据结构中使用内部和外部循环进行转置来实现它。如果将来有人读到这篇文章,唯一让我感到困惑的是没有在新列表对象中明确说明字段名称。Power BI 需要将它们识别为记录并正确填充为列。
    【解决方案2】:

    由于您的最终目标是将此数据集导入 powerBI,因此最好使用 dataframe,因为在 powerBI 中您必须再次将其转换为表格结构,因此从 dataframe 转换为 json 再将 json 转换为 dataframe 有点过头了。

    现在将不同长度的向量转换为数据帧,您会收到一个错误,因为数据帧中的元素需要具有相同的长度。所以诀窍是使这些元素的长度相同,方法是用 NA(或任何占位符,如“空白”)填充额外的元素。

    #function to generate vectors of varying length
    temp_vectors = function(n){
      vector_list = vector('list', n)
      max_size = 0
      
      for(i in 1:n){
        vec_size = sample(1:20, 1)
        vector_list[[i]] = sample(1:10, vec_size, replace=TRUE)
        if(max_size < vec_size) max_size = vec_size
      }
      
      return(list('max_size' = max_size, 'vector_list' = vector_list))
    }
    
    x = temp_vectors(10)
    vectors = x[['vector_list']]
    n = x[['max_size']]
    
    #the above code produces the following vector
    vectors[1:2]
    #> [[1]]
    #>  [1] 6 8 5 5 9 2 1 2 4 7 3 8
    #> 
    #> [[2]]
    #> [1] 1 4 8 8 7 9
    
    #for loop to fill the extra places with NA
    for(i in 1:10){
      if(length(vectors[[i]] != n)){
        length(vectors[[i]]) = n
      }
    }
    
    vectors[1:2]
    #> [[1]]
    #>  [1]  6  8  5  5  9  2  1  2  4  7  3  8 NA NA NA NA NA NA NA NA
    #> 
    #> [[2]]
    #>  [1]  1  4  8  8  7  9 NA NA NA NA NA NA NA NA NA NA NA NA NA NA
    
    #combining the vectors into df
    df = data.frame(vectors)
    colnames(df) = paste0('col.', 1:ncol(df))
    df
    #>    col.1 col.2 col.3 col.4 col.5 col.6 col.7 col.8 col.9 col.10
    #> 1      6     1     3     7     8     6     5     3     6      9
    #> 2      8     4    NA     7    10     8     5     1     8     NA
    #> 3      5     8    NA    10     5     9     7    NA     1     NA
    #> 4      5     8    NA     4     4     2     8    NA     8     NA
    #> 5      9     7    NA    NA     6     6     6    NA     9     NA
    #> 6      2     9    NA    NA     5     4     7    NA     4     NA
    #> 7      1    NA    NA    NA     1     1     2    NA     8     NA
    #> 8      2    NA    NA    NA     9     7     6    NA     5     NA
    #> 9      4    NA    NA    NA     4     8    10    NA     8     NA
    #> 10     7    NA    NA    NA     3     6    NA    NA     1     NA
    #> 11     3    NA    NA    NA     1     6    NA    NA     9     NA
    #> 12     8    NA    NA    NA     6     7    NA    NA     8     NA
    #> 13    NA    NA    NA    NA     6     8    NA    NA    10     NA
    #> 14    NA    NA    NA    NA     2     8    NA    NA    10     NA
    #> 15    NA    NA    NA    NA     1     9    NA    NA     5     NA
    #> 16    NA    NA    NA    NA     2     3    NA    NA     2     NA
    #> 17    NA    NA    NA    NA     1     1    NA    NA    NA     NA
    #> 18    NA    NA    NA    NA     6     6    NA    NA    NA     NA
    #> 19    NA    NA    NA    NA    NA     9    NA    NA    NA     NA
    #> 20    NA    NA    NA    NA    NA     9    NA    NA    NA     NA
    

    由reprex package (v0.3.0) 于 2020-07-04 创建

    请注意,您可以对 800 个向量执行相同操作,遍历它们并将它们的大小更改为最长向量的大小,额外的索引将自动填充 NA。

    【讨论】:

    • 这太棒了 - 非常感谢!我在 Power BI 中看不到连接到数据框的选项,是否必须通过 R 脚本?如果有人可以提供该解决方案,我仍然很想知道如何使用 JSON 来完成。
    • 您可以使用write.csv(df, 'filename.csv')将数据框导出到csv文件中,然后导入到powerBI中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 2020-05-22
    • 2020-08-06
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2021-11-25
    相关资源
    最近更新 更多