r - 重新列出包含数据框的列表
问题描述
我有要编辑的嵌套列表。为了以一种方便的方式这样做,我想使用unlist
and relist
。问题relist
似乎不是对底层结构的尊重:
# Some list
my_list <- list(vec = 'string',
df = data.frame(X=0,Y=0,Z=0))
str(my_list)
# List of 2
# $ vec: chr "string"
# $ df :'data.frame': 1 obs. of 3 variables:
# ..$ X: num 0
# ..$ Y: num 0
# ..$ Z: num 0
# Unlist to modify nested content
my_unlist <- unlist(my_list)
str(my_unlist)
# Named chr [1:4] "string" "0" "0" "0"
# - attr(*, "names")= chr [1:4] "vec" "df.X" "df.Y" "df.Z"
# Write some data
my_unlist[c("df.X","df.Y","df.Z")] <- c(0,1,1)
str(my_unlist)
# Named chr [1:4] "string" "0" "1" "1"
# - attr(*, "names")= chr [1:4] "vec" "df.X" "df.Y" "df.Z"
# Relist
my_relist <- relist(flesh = my_unlist, skeleton = my_list)
str(my_relist)
# List of 2
# $ vec: chr "string"
# $ df : Named chr [1:3] "0" "1" "1"
# ..- attr(*, "names")= chr [1:3] "X" "Y" "Z"
重新列出时,您可以看到列表元素(df
如果不再是数据框)。
这是一个手动解决方法
# A manual work-around
my_relist$df <- setNames(data.frame(t(as.numeric(my_relist$df)), stringsAsFactors = FALSE),
names(my_relist$df))
str(my_relist)
# List of 2
# $ vec: chr "string"
# $ df :'data.frame': 1 obs. of 3 variables:
# ..$ X: num 0
# ..$ Y: num 1
# ..$ Z: num 1
但这并没有多大帮助,因为我想任意执行此操作。
理想情况下,我会拥有一个在保留结构的同时填充my_list
内容的函数。my_unlist
所以预期的输出将是
my_relist
# $vec
# [1] "string"
#
# $df
# X Y Z
# 1 0 1 1
编辑
这是一些示例数据以及更详细的示例
# Sample data: a simple json
test_json <- '{
"email": "string",
"locations": [
{
"address": {
"city": "string",
"country": "string",
"houseNr": "string",
"state": "string",
"streetName": "string",
"zipCode": "string"
},
"latitude": 0,
"longitude": 0,
"name": "string"
}
],
"phone": "string"
}'
# Reading the json sample
json <- jsonlite::fromJSON(test_json)
# Now we unlist json so that we can easily modify nested elements
json_unlist <- unlist(json)
# Let's add a few address components
fields_to_modify <- c("locations.address.houseNr","locations.address.streetName","locations.address.city","locations.address.country")
json_unlist[fields_to_modify] <- c("1", "Boulevard de Londres","Casablanca","Morocco")
# Now we want to convert it back to json
# First step: we must relist
attempt <- relist(flesh = json_unlist, skeleton = json)
attempt$locations
# address latitude longitude name
# "Casablanca" "Morocco" "1" "string"
# <NA> <NA> <NA> <NA>
# "Boulevard de Londres" "string" "0" "0"
# <NA>
# "string"
解决方案
使用json
from the question,请注意,例如,以下内容具有相同的含义:
json[["locations"]][["address"]][["city"]]
json[[c("locations", "address", "city")]]
并假设在 unlist 对象的命名中使用点,如问题所示,我们可以Map
这样使用:
setList <- function(List, Unlist) {
nms <- names(Unlist)
Map(function(x, y) List[[x]] <<- Unlist[[y]], strsplit(nms, "\\."), nms)
List
}
setList(my_list, my_unlist)
setList(json, json_unlist)
推荐阅读
- amazon-web-services - 如何在没有 Application Load Balancer 的情况下将流量路由到 ECS Fargate 实例
- java - 我应该使用什么 proguard 规则来使 javaMailApi 完美工作?
- ruby - RSpec:对类似的 it 块使用 each 循环
- reporting-services - Visual Studio 2012 中的 Neodynamic QR 码报告无法付款 (UPNQR)
- ruby-on-rails - 错误:nil:NilClass 的未定义方法“年份”
- python - 如何在熊猫的数据框中获得具有某些条件的先前值
- java - 如果嵌套的 Optional 为空,则返回另一个 Optional
- javascript - TypeError:e.removeHeader 不是 nextjs 中的函数
- nexus - 如何在 Sonatype Nexus 3 中删除具有给定版本的所有软件包
- node.js - 如何合计计算字段的每个枚举的总数?