提问人:Aku-Ville Lehtimäki 提问时间:10/10/2023 最后编辑:Uwe KeimAku-Ville Lehtimäki 更新时间:10/11/2023 访问量:79
折叠一种特殊的列表结构
Collapsing a special kind of list structure
问:
我在 R 中有一个以下类型的列表:
List of 4
$ :List of 4
..$ prices : num [1:5] -3.68 -1.5 1.71 1.75 -0.67
..$ lower : num -2.92
..$ midpoint: num 1
..$ upper : num 4.92
$ :List of 4
..$ prices : num [1:5] 0.15395 0.00512 0.02635 0.0388 0.17721
..$ lower : num 0.00422
..$ midpoint: num 0.167
..$ upper : num 0.615
$ :List of 4
..$ prices : num [1:5, 1:3] 0.841 0.514 1.443 1.096 0.913 ...
..$ lower : num [1:3] -0.96 0.04 1.04
..$ midpoint: num [1:3] 1 2 3
..$ upper : num [1:3] 2.96 3.96 4.96
$ :List of 4
..$ prices : num [1:5] 6.78 -0.28 2.565 0.553 14.275
..$ lower : num -4.84
..$ midpoint: num 3
..$ upper : num 10.8
上层列表中的第一项、第二项和第四项应按原样进行,但第三项应折叠为三个单独的项。因此,最终结果应如下所示:
List of 4
$ :List of 4
..$ prices : num [1:5] -3.68 -1.5 1.71 1.75 -0.67
..$ lower : num -2.92
..$ midpoint: num 1
..$ upper : num 4.92
$ :List of 4
..$ prices : num [1:5] 0.15395 0.00512 0.02635 0.0388 0.17721
..$ lower : num 0.00422
..$ midpoint: num 0.167
..$ upper : num 0.615
$ :List of 4
..$ prices : num [1:5] 1 2 3 ... #This should be the FIRST column in the prices matrix of the third item in the original list, 1 2 3 just for the illustration purposes
..$ lower : num -0.96
..$ midpoint: num 1
..$ upper : num 2.96
$ :List of 4
..$ prices : num [1:5] 1 2 3 ... #This should be the SECOND column in the prices matrix of the third item in the original list, 1 2 3 ... just for the illustration purposes
..$ lower : num -0.04
..$ midpoint: num 2
..$ upper : num 3.96
$ :List of 4
..$ prices : num [1:5] 1 2 3 ... #This should be the THIRD column in the prices matrix of the third item in the original list, 1 2 3 ... just for the illustration purposes
..$ lower : num 1.04
..$ midpoint: num 3
..$ upper : num 4.96
$ :List of 4
..$ prices : num [1:5] 6.78 -0.28 2.565 0.553 14.275
..$ lower : num -4.84
..$ midpoint: num 3
..$ upper : num 10.8
有没有比开始在 for 循环中填充新列表更好的方法,以便:
newlist <- list()
newlist_i <- 1 #This index increases faster than i, whenever we encounter a "compressed" list item.
for(i in 1:length(origlist)) {
if(!is.null(dim(origlist[[i]]$prices)) { #dim(vector) returns NULL
for(j in 1:ncol(prices)) {
newlist[[newlist_i+j-1]]$prices <- origlist[[i]]$prices[,j]
newlist[[newlist_i+j-1]]$lower <- origlist[[i]]$lower[j]
newlist[[newlist_i+j-1]]$midpoint <- origlist[[i]]$midpoint[j]
newlist[[newlist_i+j-1]]$upper <- origlist[[i]]$upper[j]
}
newlist_i = newlist_i + dim(origlist[[i]]$prices) - 1
} else {
newlist[[i]] <- origlist[[i]]
newlist_i = newlist_i + 1
}
}
但是for循环看起来非常丑陋和复杂。有没有更好的方法可以做到这一点?
答:
1赞
asd-tm
10/11/2023
#1
我将提供以下基本 R 解决方案:
do.call(rbind,
lapply(my_d, \(x){
rbind(x$prices |> matrix(5), x$lower, x$midpoint, x$upper) |> t()
})
) |> apply(MARGIN = 1, \(x) {
list(
prices = x[1:5],
lower = x[6],
midpoint = x[7],
upper = x[8]
)
})
或者,如果长度未知:prices
do.call(rbind,
lapply(my_d, \(x){
cbind(x$prices |> matrix(length(x$lower), byrow = T), x$lower, x$midpoint, x$upper)
})
) |> apply(MARGIN = 1, \(x) {
list(
prices = x[1:(length(x) - 3)],
lower = x[length(x) - 2],
midpoint = x[length(x) - 1],
upper = x[length(x)]
)
})
两个脚本返回相同的输出:
[[1]]
[[1]]$prices
[1] 1.9196255 0.1770681 2.3306149 -0.8893725 0.7117880
[[1]]$lower
[1] 1.317551
[[1]]$midpoint
[1] 0.4215168
[[1]]$upper
[1] -0.8721538
[[2]]
[[2]]$prices
[1] -1.0674630 0.2179483 -2.2493795 0.2747926 -1.3451170
[[2]]$lower
[1] 1.444299
[[2]]$midpoint
[1] 1.212617
[[2]]$upper
[1] 0.1006223
[[3]]
[[3]]$prices
[1] -0.3124539 0.8772849 0.4090815 0.4909305 -0.9445474
[[3]]$lower
[1] -1.182347
[[3]]$midpoint
[1] -1.285585
[[3]]$upper
[1] -1.537147
[[4]]
[[4]]$prices
[1] -0.6609199 0.2626416 -0.2137965 -0.2261824 -0.8723562
[[4]]$lower
[1] -1.693114
[[4]]$midpoint
[1] -1.607736
[[4]]$upper
[1] -0.05325191
[[5]]
[[5]]$prices
[1] -0.8811282 -0.8030718 2.4720077 -0.1622402 0.9657835
[[5]]$lower
[1] -0.4743322
[[5]]$midpoint
[1] -0.9583107
[[5]]$upper
[1] 0.264364
[[6]]
[[6]]$prices
[1] -0.1863864 0.2615337 -0.3725853 -0.1614547 0.4465152
[[6]]$lower
[1] 0.03844349
[[6]]$midpoint
[1] -0.5716921
[[6]]$upper
[1] -1.85495
使用数据:
my_d <- list(
list(prices = rnorm(5),
lower = rnorm(1),
midpoint = rnorm(1),
upper = rnorm(1)),
list(prices = rnorm(5),
lower = rnorm(1),
midpoint = rnorm(1),
upper = rnorm(1)),
list(prices = matrix(rnorm(5*3), 5),
lower = rnorm(3),
midpoint = rnorm(3),
upper = rnorm(3)),
list(prices = rnorm(5),
lower = rnorm(1),
midpoint = rnorm(1),
upper = rnorm(1))
)
1赞
Onyambu
10/11/2023
#2
您可以使用 + + 使用 @asd-tm
中的数据(在到期时给予积分)ModifyList
asplit
lapply
origlist <- md
lapply(origlist, \(x)
if(length(dim(x$prices)))
do.call(Map, c(list,modifyList(x, list(prices = asplit(x$prices,2)))))
else list(x)
)|>unlist(FALSE)
List of 6
$ :List of 4
..$ prices : num [1:5] 1.097 0.435 -0.326 1.149 0.994
..$ lower : num 0.548
..$ midpoint: num 0.239
..$ upper : num -0.628
$ :List of 4
..$ prices : num [1:5] 1.361 -0.6 2.187 1.533 -0.236
..$ lower : num -1.03
..$ midpoint: num -0.71
..$ upper : num 0.257
$ :List of 4
..$ prices : num [1:5(1d)] -0.247 -0.348 -0.952 -0.045 -0.785
..$ lower : num -0.641
..$ midpoint: num 0.118
..$ upper : num -0.256
$ :List of 4
..$ prices : num [1:5(1d)] -1.668 -0.38 0.919 -0.575 0.608
..$ lower : num -0.85
..$ midpoint: num -0.947
..$ upper : num 1.84
$ :List of 4
..$ prices : num [1:5(1d)] -1.6179 -0.0556 0.5194 0.3012 0.1057
..$ lower : num -1.02
..$ midpoint: num -0.491
..$ upper : num -0.652
$ :List of 4
..$ prices : num [1:5] 0.2354 0.078 -0.9619 -0.0713 1.4446
..$ lower : num 0.452
..$ midpoint: num 0.0412
..$ upper : num -0.422
评论
dput(origlist)