Unlist elements from unequal vectors at the last level of a nested list while keeping the sublist name in R

huangapple go评论59阅读模式
英文:

Unlist elements from unequal vectors at the last level of a nested list while keeping the sublist name in R

问题

以下是您要翻译的代码部分的翻译:

我有以下嵌套列表对象,其中包含不等长的数值向量在最后一级:

```R
preallocated_vector_quad <- c(1:2)
preallocated_vector_lin  <- c(3:5)
specification_list       <- list(quadratic = preallocated_vector_quad, linear = preallocated_vector_lin)
effects_list             <- list(fixed     = specification_list,        mixed = specification_list)
object_list              <- list(fit       = effects_list,              draws = effects_list)
str(object_list)

List of 2
 $ fit  :List of 2
  ..$ fixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5
  ..$ mixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5
 $ draws:List of 2
  ..$ fixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5
  ..$ mixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5

我想要获得一个输出,其中包含最后一级的每个值,以及它从列表中获取的具体位置(例如 3fixed.linear)。最好不使用 tidyverse 函数。理想的输出可以是宽格式或长格式:

    value     fixed.quadratic fixed.linear mixed.quadratic mixed.linear
[1]  1               1               0               0               0
[2]  2               1               0               0               0
[3]  3               0               1               0               0
[4]  4               0               1               0               0
[5]  5               0               1               0               0
[6]  1               0               0               1               0
[7]  2               0               0               1               0
[8]  3               0               0               0               1
[9]  4               0               0               0               1
[10] 5               0               0               0               1
       value         type
    [1]  1        'fixed.quadratic' 
    [2]  2        'fixed.quadratic'  
    [3]  3        'fixed.linear'  
    [4]  4        'fixed.linear'  
    [5]  5        'fixed.linear'  
    [6]  1        'mixed.quadratic'  
    [7]  2        'mixed.quadratic'  
    [8]  3        'mixed.linear'  
    [9]  4        'mixed.linear'  
    [10] 5        'mixed.linear'  

我尝试了类似的问题的解决方案,但它们没有给我期望的结果,因为它们要么具有等长的向量,要么不需要保留子列表名称。到目前为止,我最接近的解决方案是:

>unlist(object_list$draws, recursive = FALSE)

$fixed.quadratic
[1] 1 2

$fixed.linear
[1] 3 4 5

$mixed.quadratic
[1] 1 2

$mixed.linear
[1] 3 4 5

然而,贴出的解决方案在向量长度不等的情况下会出现错误:

> do.call(dplyr::bind_rows,unlist(object_list$draws, recursive = FALSE) )
Error:
! Tibble columns must have compatible sizes.
* Size 2: Columns `fixed.quadratic` and `mixed.quadratic`.
* Size 3: Columns `fixed.linear` and `mixed.linear`.
i Only values of size one are recycled.

其他尝试会得到一个带有数字后缀的命名数值向量,这可以通过操作属性和字符串来获得我期望的输出,但似乎效率非常低下。

> unlist((unlist(object_list$draws, recursive = FALSE)))
fixed.quadratic1 fixed.quadratic2    fixed.linear1    fixed.linear2 
               1                2                3                4 
   fixed.linear3 mixed.quadratic1 mixed.quadratic2    mixed.linear1 
               5                1                2                3 
   mixed.linear2    mixed.linear3 
               4                5 
英文:

I have the following nested list object, containing unequal length numeric vectors at the last level:

preallocated_vector_quad <- c(1:2)
preallocated_vector_lin  <- c(3:5)
specification_list       <- list(quadratic = preallocated_vector_quad, linear = preallocated_vector_lin)
effects_list             <- list(fixed     = specification_list,        mixed = specification_list)
object_list              <- list(fit       = effects_list,              draws = effects_list)
str(object_list)

List of 2
 $ fit  :List of 2
  ..$ fixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5
  ..$ mixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5
 $ draws:List of 2
  ..$ fixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5
  ..$ mixed:List of 2
  .. ..$ quadratic: int [1:2] 1 2
  .. ..$ linear   : int [1:3] 3 4 5

I would like to obtain an output that has every value of the last level, together with the specific location within the list from which it was obtained (e.g. 3 and fixed.linear). Preferably no tidyverse functions. The ideal output could be either in wide or long format:

    value     fixed.quadratic fixed.linear mixed.quadratic mixed.linear
[1]  1               1               0               0               0
[2]  2               1               0               0               0
[3]  3               0               1               0               0
[4]  4               0               1               0               0
[5]  5               0               1               0               0
[6]  1               0               0               1               0
[7]  2               0               0               1               0
[8]  3               0               0               0               1
[9]  4               0               0               0               1
[10] 5               0               0               0               1
       value         type
    [1]  1        'fixed.quadratic' 
    [2]  2        'fixed.quadratic'  
    [3]  3        'fixed.linear'  
    [4]  4        'fixed.linear'  
    [5]  5        'fixed.linear'  
    [6]  1        'mixed.quadratic'  
    [7]  2        'mixed.quadratic'  
    [8]  3        'mixed.linear'  
    [9]  4        'mixed.linear'  
    [10] 5        'mixed.linear'  

I have tried solutions to similar questions in this site but they do not give me the expected result, as either they have equal size length vectors or they do not need to maintain the sublist name. My closest solution so far is:

>unlist(object_list$draws, recursive = FALSE)

$fixed.quadratic
[1] 1 2

$fixed.linear
[1] 3 4 5

$mixed.quadratic
[1] 1 2

$mixed.linear
[1] 3 4 5

However, posted solutions break with the unequal vector length, e.g.:

> do.call(dplyr::bind_rows,unlist(object_list$draws, recursive = FALSE) )
Error:
! Tibble columns must have compatible sizes.
* Size 2: Columns `fixed.quadratic` and `mixed.quadratic`.
* Size 3: Columns `fixed.linear` and `mixed.linear`.
i Only values of size one are recycled.

Other attempts get a named numeric vector which appends a digit to the list name for every element in it, which can be worked to get my desired output by manipulating attributes and strings, but seems highly unefficient.

> unlist((unlist(object_list$draws, recursive = FALSE)))
fixed.quadratic1 fixed.quadratic2    fixed.linear1    fixed.linear2 
               1                2                3                4 
   fixed.linear3 mixed.quadratic1 mixed.quadratic2    mixed.linear1 
               5                1                2                3 
   mixed.linear2    mixed.linear3 
               4                5 

答案1

得分: 1

你在帖子末尾提到了这个解决方案:您可以取消列出(使用默认的recursive = TRUE),并从名称中删除尾随的数字:

unlisted <- unlist(object_list$draws)

data.frame(
  value = unname(unlisted),
  type = gsub(""[0-9]*$"", """", names(unlisted))
)
   value            type
1      1 fixed.quadratic
2      2 fixed.quadratic
3      3    fixed.linear
4      4    fixed.linear
5      5    fixed.linear
6      1 mixed.quadratic
7      2 mixed.quadratic
8      3    mixed.linear
9      4    mixed.linear
10     5    mixed.linear

这个替代方法在我看来有点繁琐,但避免了任何字符串操作:

unlisted <- unlist(object_list$draws, recursive = FALSE)

dfs <- lapply(names(unlisted), \(x) data.frame(value = unlisted[[x]], type = x))

do.call(rbind, dfs)
英文:

You hinted at this solution at the end of your post; you can unlist (with the default recursive = TRUE), and remove the trailing digits from the names:

unlisted <- unlist(object_list$draws)

data.frame(
  value = unname(unlisted),
  type = gsub("[0-9]*$", "", names(unlisted))
)
   value            type
1      1 fixed.quadratic
2      2 fixed.quadratic
3      3    fixed.linear
4      4    fixed.linear
5      5    fixed.linear
6      1 mixed.quadratic
7      2 mixed.quadratic
8      3    mixed.linear
9      4    mixed.linear
10     5    mixed.linear

This alternative feels clunkier to me, but avoids any string manipulation:

unlisted <- unlist(object_list$draws, recursive = FALSE)

dfs <- lapply(names(unlisted), \(x) data.frame(value = unlisted[[x]], type = x))

do.call(rbind, dfs)

huangapple
  • 本文由 发表于 2023年3月3日 22:27:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628313.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定