如何在R中递归地获取列表元素的属性



我有一个嵌套的list结构,其中一些元素(不是全部(具有我想要保留的属性(我已经将一些xml输出转换为list(。我正试图把它压扁成data.frame。结构是这样的:

myList <- structure(list(address = structure(list(Address = list(Line = list("xxxxxxx"), 
Line = list("xxxxxxx"), Line = list("xxxxxxx"), PostCode = list(
"XXX XXX"))), type = "Residential", verified = "Unverified"), 
amount = structure(list(paymentAmount = list(maxAmount = list(
amountPart = structure(list(Amount = list("0.00")), component = "Standard"), 
amountPart = structure(list(Amount = list("0.00")), component = "Thing1"), 
amountPart = structure(list(Amount = list("0.00")), component = "Thing2"), 
amountPart = structure(list(Amount = list("0.00")), component = "Thing3"), 
amountPart = structure(list(Amount = list("0.00")), component = "Thing4"), 
amountPart = structure(list(Amount = list("100.00")), component = "Thing5"), 
amountPart = structure(list(Amount = list("0.00")), component = "Thing6")), 
otherAmount = list(Amount = list("0.00")), 
discount = list("0.00"), 
transition = list(
"0.00"), discounts = list(), regularPayment = list(
"200.00")), 
paymentInfo = list(income = structure(list(
net = list("0")), refNumber = "xxxxxxx"))), 
paymentDate = "2021-03-22", startDate = "2021-02-16", endDate = "2021-03-15")), 
type = "Normal")

我尝试过rapply(myList, attributes),但似乎只是返回了NULL

我还尝试过在递归函数中使用循环:

get_attributes <- function(myList, attribute_list = NULL) {
if (is.null(attribute_list)) attribute_list <- list()
for (i in seq_along(myList)) {
if (is.list(myList[[i]])) {
attribute_list <- c(attribute_list, sapply(myList[[i]], attributes))
attribute_list <- get_attributes(myList[[i]], attribute_list)
} else {
attribute_list <- c(attribute_list, attributes(myList[[i]]))
}
}
attribute_list
}

一旦我得到了属性列表,我就想把它们放在一行data.frame中——类似于data.frame(address.type = "Residential", address.verified = "Unverified", component.1 = "Standard", component.2 = "Thing1"

带有循环的函数有点乱,不太"R",而且它似乎还吐出了很多我不想要的重复元素。有人知道如何更优雅地实现这一点吗?

更新

我已经对此进行了改进,这似乎很有效,但我只是不知道如何使用purrr*apply函数之一来代替循环:

get_attributes <- function(myList, attribute_list = NULL, prefix = NULL) {

if (is.null(attribute_list)) {
attribute_list <- list()
}
if (is.null(prefix)) {
prefix <- ""
}

for (i in seq_along(myList)) {
name <- names(myList)[i]
attrs <- attributes(myList[[i]])
if (!is.null(attrs)) {
names(attrs) <- paste0(prefix, name, ".", names(attrs))
attrs <- attrs[!grepl("\.names$", names(attrs))]
attribute_list <- c(attribute_list, attrs)
}
if (is.list(myList[[i]])) {
attribute_list <- get_attributes(myList[[i]],
attribute_list,
paste0(prefix, name, "."))
}
}
attribute_list

}
do.call(data.frame, get_attributes(myList))

您可以收集所有可用的属性,并保留您感兴趣的属性。

library(purrr)
map_df(myList, ~map_chr(attributes(.x), toString))
#  names                      type        verified   paymentDate startDate  endDate   
#  <chr>                      <chr>       <chr>      <chr>       <chr>      <chr>     
#1 Address                    Residential Unverified NA          NA         NA        
#2 paymentAmount, paymentInfo NA          NA         2021-03-22  2021-02-16 2021-03-15

最新更新