Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 操作嵌套列表中的值_R_Json_Purrr - Fatal编程技术网

R 操作嵌套列表中的值

R 操作嵌套列表中的值,r,json,purrr,R,Json,Purrr,我试图从API读取JSON元数据,在R中操作它,然后发回 然而,当我通过jsonlite获取元数据时,真/假值被读取为逻辑值并变成大写。API将不接受大写的TRUE/FALSE返回。因此,我需要将所有TRUE/FALSE替换为“TRUE”和“FALSE”作为字符,但保留与输入相同的嵌套列表结构 问题在于,这些是JSON键/值对和嵌套数组,因此真/假值嵌套在不同级别。我还只想更改“TRUE”或“FALSE”的值,而不是包含“TRUE”或“FALSE”的字符串 我尝试过应用函数族、purrr映射和递

我试图从API读取JSON元数据,在R中操作它,然后发回

然而,当我通过jsonlite获取元数据时,真/假值被读取为逻辑值并变成大写。API将不接受大写的TRUE/FALSE返回。因此,我需要将所有TRUE/FALSE替换为“TRUE”和“FALSE”作为字符,但保留与输入相同的嵌套列表结构

问题在于,这些是JSON键/值对和嵌套数组,因此真/假值嵌套在不同级别。我还只想更改“TRUE”或“FALSE”的值,而不是包含“TRUE”或“FALSE”的字符串

我尝试过应用函数族、purrr映射和递归for循环

#read data via API
dashitem_api<-paste0("api/metadata.json?filter=id:like:",dashitem_old_idprefix)
url<-paste0(baseurl,dashitem_api)

dash_items<-jsonlite::fromJSON(content(GET(url),"text")[])
#通过API读取数据

dashitem\u api列表对象中的值实际上是
“TRUE”
(R字符串)还是
TRUE
(R逻辑)?如果它们是有效的R逻辑(与您共享的示例数据不同),那么
jsonlite::toJSON
将更正它们

x <- list(
  partA = list(numbers = 1:3, boolean = T),
  partB = list(
    nested = list(
      numbers = 4:6, 
      nestB = list(boolean = c(FALSE, FALSE))
      )
    )
)

jsonlite::toJSON(x, pretty = T)
在数据处理步骤中,似乎不太可能生成字符串
“TRUE”
“FALSE”
更新:,这实际上是问题所在!),因此希望这能起作用
jsonlite::fromJSON
[true,false]
转换为
c(true,false)
,而
到JSON
则会做相反的转换

确保数据帧被强制为相同的格式可能需要一些检查
toJSON
有一些选项:
dataframe=
可以

  • ”(默认值)
  • “nestB”:{“boolean”:[false,false]}
    ,或
  • 值”
    “nestB”:[[false],[false]]
但是,如果您正在使用默认值来读取API响应,则不太可能需要更改将其发送回的默认值


更新:
这个用例调用了
rappy
来搜索整个列表对象并替换某些元素。因为调用的是
gsub
,所以每个元素都被强制为一个字符,包括任何数字或逻辑值。为了防止这种情况发生,您可以使用
一些\u output\u object Hi Brian感谢您的响应!但是,这些值在数据处理之前确实是逻辑值,但在数据处理期间转换为字符串。见我的编辑上面。也许我应该直接在JSON对象上尝试替换?我不知道,但奇怪的是,我不能简单地用“真”替换所有“真”值。@bodo你能发布实际的JSON响应对象吗(如果需要,可以手动匿名)?用
“TRUE”
替换
“TRUE”
无论如何都不会解决你的问题,因为当你重新整理列表时,你会遇到问题:
{“x”:TRUE}
vs
{“x”:“TRUE”}
你可能只需要更改你的
rappy
呼叫:
new\u-dash谢谢,这很有效!!!诀窍是classes=“character”选项。我都没想到!但现在API在POST请求时正确读取JSON输出。
new_dash<-list(charts=list(list(id="abcd123",shared="FALSE",translations=list(),
                 dimensions=data.frame(thisyear="FALSE",last6Months="TRUE"),
params=list(reportingPeriod="FALSE",reportingUnit="FALSE"),
dimensionItems=list(type="DATA_ELEMENT",dataElement=list(id="ZYXW987"))),

               list(id="abcd4567",shared="FALSE",translations=list(),
                dimensions=data.frame(thisyear="FALSE",last6Months="TRUE"),
                params=list(reportingPeriod="FALSE",reportingUnit="TRUE"),
dimensionItems=list(type="DATA_ELEMENT",dataElement=list(id="ZYXW988")))),

reportTables=list(id="abcd124",title="false positives", shared="FALSE",translations=list(),
 dimensions=data.frame(thisyear="FALSE",last6Months="TRUE"),
params=list(reportingPeriod="FALSE",reportingUnit="FALSE"),
dimensionItems=list(type="DATA_ELEMENT",dataElement=list(id="ZYXW989"))))

#solution 1
change_list <- function(x) {
  for (i in seq_along(x)) {
    value <- x[[i]]
    if (is.list(value)) {
      x[[i]] <- change_list(value)
    } else {
      if (as.character(value)=="FALSE") {
        x[[i]] <- tolower(value)
      }
    }
  }
  x
}
test1<-change_list(new_dash)

#solution 2
test2<-lapply(new_dash, function(x) {
  id <- x == "FALSE"
  x[id] <- "false"
  return(x)
})


#solution 3
test3<- c(map(new_dash$charts, 
~modify_if(~x=="TRUE", tolower)), 
recursive= TRUE)

x <- list(
  partA = list(numbers = 1:3, boolean = T),
  partB = list(
    nested = list(
      numbers = 4:6, 
      nestB = list(boolean = c(FALSE, FALSE))
      )
    )
)

jsonlite::toJSON(x, pretty = T)
{
  "partA": {
    "numbers": [1, 2, 3],
    "boolean": [true]
  },
  "partB": {
    "nested": {
      "numbers": [4, 5, 6],
      "nestB": [
        {
          "boolean": false
        },
        {
          "boolean": false
        }
      ]
    }
  }
}