> mylist
$result.1
truth model1 model2
1 1 2 1.0
2 2 3 -0.5
3 3 -1 4.0
$result.2
truth model1 model2
1 1 1 2
2 2 4 2
3 3 4 1
我有一個包含許多子串列的串列。在上面的例子中,它是 2,但是子串列的數量可以超過 2。
在各子表,有一個data.frame包含truth和預測的model1和model2。我想重塑我的串列,以便每個子串列對應于一個特定的模型,即,我想:
$model1
truth result.1 result.2
1 1 2 1
2 2 3 4
3 3 -1 4
$model2
truth result.1 result.2
1 1 1.0 2
2 2 -0.5 2
3 3 4.0 1
有沒有一種快速的方法可以以這種方式重塑串列?
uj5u.com熱心網友回復:
使用cbind的do.call。
lapply(1:length(L), \(i) do.call(cbind, c(L$result.1[, 1, F], lapply(L, `[[`, i)))) |>
setNames(names(L))
# $model1
# truth result.1 result.2
# [1,] 1 2 1
# [2,] 2 3 4
# [3,] 3 -1 4
#
# $model2
# truth result.1 result.2
# [1,] 1 1.0 2
# [2,] 2 -0.5 2
# [3,] 3 4.0 1
注: R >= 4.1
資料:
L <- list(result.1 = structure(list(truth = 1:3, model1 = c(2, 3,
-1), model2 = c(1, -0.5, 4)), class = "data.frame", row.names = c(NA,
-3L)), result.2 = structure(list(truth = 1:3, model1 = c(1, 4,
4), model2 = c(2, 2, 1)), class = "data.frame", row.names = c(NA,
-3L)))
uj5u.com熱心網友回復:
考慮使用鏈合并迭代不同的模型列名稱:
newlist <- sapply(
names(mylist$result.1)[-1],
function(nm) {
df <- Reduce(
function(x, y) merge(x, y, by="truth"),
lapply(mylist, `[`, c("truth", nm))
)
df <- setNames(df, c("truth", paste0("result.", 1:(ncol(df)-1))))
},
simplify = FALSE
)
newlist
$model1
truth result.1 result.2
1 1 2 1
2 2 3 4
3 3 -1 4
$model2
truth result.1 result.2
1 1 1.0 2
2 2 -0.5 2
3 3 4.0 1
uj5u.com熱心網友回復:
這是一個 tidyverse 選項:如果您將所有資料框系結到一個并使用串列的名稱來標記資料來自哪個模型,則它成為一個簡單的轉置操作。然后您可以再次按型號拆分。
我添加了一個額外的模型來測驗它是如何擴展的:您不會對試驗次數或模型或其名稱進行硬編碼,如果一次試驗中缺少模型,您將獲得 NA 但不會出現錯誤。
library(dplyr)
mylist %>%
bind_rows(.id = "trial") %>%
tidyr::pivot_longer(matches("model\\d "), names_to = "model") %>%
tidyr::pivot_wider(names_from = trial) %>%
split(.$model) %>%
purrr::map(select, -model)
#> $model1
#> # A tibble: 3 × 3
#> truth result.1 result.2
#> <int> <dbl> <dbl>
#> 1 1 2 1
#> 2 2 3 4
#> 3 3 -1 4
#>
#> $model2
#> # A tibble: 3 × 3
#> truth result.1 result.2
#> <int> <dbl> <dbl>
#> 1 1 1 2
#> 2 2 -0.5 2
#> 3 3 4 1
#>
#> $model3
#> # A tibble: 3 × 3
#> truth result.1 result.2
#> <int> <dbl> <dbl>
#> 1 1 0 9
#> 2 2 4 5
#> 3 3 2 2
來自 jay.sf's answer 的資料加上另一個虛擬列
mylist <- list(result.1 = structure(list(truth = 1:3, model1 = c(2, 3, -1), model2 = c(1, -0.5, 4), model3 = c(0, 4, 2)), class = "data.frame", row.names = c(NA, -3L)), result.2 = structure(list(truth = 1:3, model1 = c(1, 4, 4), model2 = c(2, 2, 1), model3 = c(9, 5, 2)), class = "data.frame", row.names = c(NA, -3L)))
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/398313.html
下一篇:在串列中查找最舊并回傳最舊的串列
