R 在嵌套列表中搜索名称并更新名称

R Search for name in nested list and update the name

提问人:sutsabs 提问时间:5/27/2023 最后编辑:sutsabs 更新时间:6/1/2023 访问量:60

问:

我有一个嵌套列表对象。在嵌套列表中,我想查找是否有名为“StartDate”的项目,并将名称更新为“OccurrenceStartDate”。 现在,我可以重新申请列出名称并查找名称并手动更新。有没有更好的方法?我需要自动化这个过程。cc

此外,我还需要更新 OccurrenceStartDate 值的格式。我可以手动分配格式。

cc <- list(ConceptSets = list(list(id = 0L, name = "test cs", expression = list(
        items = list(list(concept = list(CONCEPT_ID = 1569193L, CONCEPT_NAME = "Cerebral infarction", 
                                         STANDARD_CONCEPT = "", STANDARD_CONCEPT_CAPTION = "", 
                                         INVALID_REASON = "V", INVALID_REASON_CAPTION = "Valid", 
                                         CONCEPT_CODE = "I63", DOMAIN_ID = "Condition", VOCABULARY_ID = "ICD10CM", 
                                         CONCEPT_CLASS_ID = "3-char nonbill code"), isExcluded = FALSE, 
                          includeDescendants = TRUE, includeMapped = FALSE))))), 
        PrimaryCriteria = list(CriteriaList = list(list(ConditionOccurrence = list(
            CodesetId = 0L, Age = list(Op = "eq", Value = 15L), StartDate = list(
                Op = "bt", Value = structure(17532, class = "Date"), 
                Extent = structure(18628, class = "Date"))))), ObservationWindow = list(
                    PriorDays = 0L, PostDays = 0L), PrimaryCriteriaLimit = list(
                        Type = "First")), QualifiedLimit = list(Type = "First"), 
        ExpressionLimit = list(Type = "First"), InclusionRules = list(), 
        CensoringCriteria = list(), CollapseSettings = list(CollapseType = "ERA", 
                                                            EraPad = 0L), CensorWindow = structure(list(), names = character(0)), 
        cdmVersionRange = ">=5.0.0")

    names(rapply(cc, function(x) head(x)))
    
    names(cc$PrimaryCriteria$CriteriaList[[1]]$ConditionOccurrence)[3] <- "OccurrenceStartDate"
    
    cc$PrimaryCriteria$CriteriaList[[1]]$ConditionOccurrence$OccurrenceStartDate$Value <- cc$PrimaryCriteria$CriteriaList[[1]]$ConditionOccurrence$OccurrenceStartDate$Value %>% format( "%m-%d-%Y")

这不会更新名称,而只是列出名称

names(rapply(cc, function(x) head(x))) %>% str_replace_all(pattern = "StartDate","OccurrenceStartDate")
r 列表 嵌套列表

评论


答:

1赞 I_O 5/27/2023 #1

具有 {data.tree} 的解决方案:

library(data.tree)

## build tree from list:
cc_tree <- FromListSimple(cc)

## update tree in place
cc_tree$Do(function(node) node$name = gsub("StartDate", "OccurrenceStartDate", node$name)) 

## retransform tree to list:
cc_renamed <- ToListSimple(cc_tree)
## > cc_renamed
$name
[1] "Root"

$cdmVersionRange
[1] ">=5.0.0"

$ConceptSets
$ConceptSets$name
[1] "ConceptSets"

## ...

$PrimaryCriteria$CriteriaList$`1`$ConditionOccurrence$OccurrenceStartDate
$PrimaryCriteria$CriteriaList$`1`$ConditionOccurrence$OccurrenceStartDate$name

## ...

1赞 Joris C. 5/28/2023 #2

这是一个解决方案,在-package(base的扩展)中使用专用选项:rrapply()rrapplyrapply()how = "names"

library(rrapply)

## rename StartDate -> OccurrenceStartDate
cc1 <- rrapply(cc, condition = \(x, .xname) .xname == "StartDate", f = \(x) "OccurrenceStartDate", classes = "list", how = "names")

## filter OccurrenceStartDate node
str(rrapply(cc1, condition = \(x, .xname) .xname == "OccurrenceStartDate", classes = "list", how = "prune"))
#> List of 1
#>  $ PrimaryCriteria:List of 1
#>   ..$ CriteriaList:List of 1
#>   .. ..$ :List of 1
#>   .. .. ..$ ConditionOccurrence:List of 1
#>   .. .. .. ..$ OccurrenceStartDate:List of 3
#>   .. .. .. .. ..$ Op    : chr "bt"
#>   .. .. .. .. ..$ Value : Date[1:1], format: "2018-01-01"
#>   .. .. .. .. ..$ Extent: Date[1:1], format: "2021-01-01"

更新:对于部分命名的嵌套列表,将空白 () 名称分配给以前未命名的列表元素。为了避免这种行为,我们可以改用:how = "names"""

cc1 <- rrapply(
  cc, 
  condition = \(x) "StartDate" %in% names(x), 
  f = \(x) { names(x)[match("StartDate", names(x))] <- "OccurrenceStartDate"; x },
  classes = c("list", "ANY"), 
  how = "recurse"
) 

这将仅修改满足参数的列表元素。condition

评论

0赞 sutsabs 6/1/2023
rraaply 函数更新名称,但它正在更改列表的结构。因此,当我必须将数据馈送到我的应用程序时,我遇到了错误。如果比较 cc 和 cc1 的 json 格式,则会导致问题的结构存在一些差异。jsonify::to_json(cc1) 与 jsonify::to_json(cc) 的结构不同
0赞 Joris C. 6/1/2023
我更新了答案,这应该只修改满足参数的列表元素的名称。condition