如何动态命名列表的元素?

时间:2019-01-21 04:01:08

标签: r

我想使用变量的内容即时命名列表的元素,怎么办?

DT <- data.table(A=LETTERS[1:3], B=letters[1:3], C= 1:9)

lapply(unique(DT$A), function(xA){
  RTN <- 
    lapply(unique(DT$B), function(xB){
        output <- DT[A == xA & B == xB]$C
         if(length(output)== 0L) {
         }else{
           c(xA, xB, output)
         }
    }) 
})

结果是

[[1]]
[[1]][[1]]
[1] "A" "a" "1" "4" "7"
[[1]][[2]]
NULL
[[1]][[3]]
NULL
[[2]]
[[2]][[1]]
NULL
[[2]][[2]]
[1] "B" "b" "2" "5" "8"
[[2]][[3]]
NULL

我想做到以下

[[A]]
[[A]][[a]]
[1] "A" "a" "1" "4" "7"
[[A]][[b]]
NULL
[[A]][[c]]
NULL
[[B]]
[[B]][[a]]
NULL
[[B]][[B]]
[1] "B" "b" "2" "5" "8"
[[B]][[c]]
NULL

此外,如何删除NULL,并使其成为完整的大小写矩阵?非常感谢。

2 个答案:

答案 0 :(得分:2)

以下是两种解决方案:

1)使用sapply并设置USE.NAMES = TRUE

2)在每个应用之前捕获名称,并在之后设置名称。

DT <- data.table(A=LETTERS[1:3], B=letters[1:3], C= 1:9)

outer_list_names <- unique(DT$A)
outer_list  <- lapply(unique(DT$A), function(xA){
  RTN_names = unique(DT$B)
  RTN <- 
    lapply(unique(DT$B), function(xB){
        output <- DT[A == xA & B == xB]$C
         if(length(output)== 0L) {
         }else{
           c(xA, xB, output)
         }
    })
  names(RTN) <- RTN_names 
})
names(outer_list) <- outer_list_names
outer_list

答案 1 :(得分:2)

我们可以创建一个命名向量来命名列表

A_vec <- setNames(unique(DT$A), unique(DT$A))
B_vec <- setNames(unique(DT$B), unique(DT$B))

lapply(A_vec, function(xA){
     RTN <- lapply(B_vec, function(xB){
     output <- DT[A == xA & B == xB]$C
     if(length(output) >  0L) {
       c(xA, xB, output)
     }
   })
})


#$A
#$A$a
#[1] "A" "a" "1" "4" "7"

#$A$b
#NULL

#$A$c
#NULL


#$B
#$B$a
#NULL

#$B$b
#[1] "B" "b" "2" "5" "8"

#$B$c
#NULL

如果您想删除NULL值,我们可以有一个Filter删除它们

lapply(A_vec, function(xA){
     RTN <- lapply(B_vec, function(xB){
     output <- DT[A == xA & B == xB]$C
     if(length(output) >  0L) {
        c(xA, xB, output)
     }
   })
   Filter(Negate(is.null), RTN)
})


#$A
#$A$a
#[1] "A" "a" "1" "4" "7"


#$B
#$B$b
#[1] "B" "b" "2" "5" "8"


#$C
#$C$c
#[1] "C" "c" "3" "6" "9"