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