使用 purrr 获取列表中相应矩阵条目的分位数
Use purrr to get quantile of corresponding matrix entries in a list
我有以下 reprex
10 个样本矩阵的列表:
# Sample of 10 3*3 matrices
z1 <- matrix(101:104, nrow = 2, ncol = 2)
z2 <- matrix(201:204, nrow = 2, ncol = 2)
z3 <- matrix(301:304, nrow = 2, ncol = 2)
z4 <- matrix(401:404, nrow = 2, ncol = 2)
z5 <- matrix(501:504, nrow = 2, ncol = 2)
z6 <- matrix(601:604, nrow = 2, ncol = 2)
z7 <- matrix(701:704, nrow = 2, ncol = 2)
z8 <- matrix(801:804, nrow = 2, ncol = 2)
z9 <- matrix(901:904, nrow = 2, ncol = 2)
z10 <- matrix(1001:1004, nrow = 2, ncol = 2)
# Combine all matrices into a single list
za <- list(z1, z2, z3, z4, z5, z6, z7, z8, z9, z10)
我们想要的是将 za
作为输入并获得 2 2*2 matrices
称为 upper_quantile
和 lower_quantile
矩阵。
本质上,这是采用上面的 10 个矩阵列表,并为 对应的条目 取上 97.5% 的分位数。较低的 2.5% 分位数也是如此。
在这种情况下,我们可以手动构造此示例的upper_quantile
矩阵,如下所示:
upper_quantile <- matrix(data = c(quantile(x = seq(101, 1001, by = 100), probs = 0.975),
c(quantile(x = seq(102, 1002, by = 100), probs = 0.975)),
c(quantile(x = seq(103, 1003, by = 100), probs = 0.975)),
c(quantile(x = seq(104, 1004, by = 100), probs = 0.975)))
, nrow = 2
, ncol = 2
, byrow = FALSE)
upper_quantile
#> [,1] [,2]
#> [1,] 978.5 980.5
#> [2,] 979.5 981.5
我想了解如何使用 purrr
或 tidyverse
工具来做到这一点,因为我一直在努力避免列表上的繁琐循环,并希望自动调整尺寸。
有人可以帮忙吗?
这里有一个稍微笨拙的方法,它至少将所有内容都放在一个管道中。它假设所有矩阵都是相同的维度,这必须是真实的,否则所需的输出没有多大意义。在 purrr
中使用矩阵总是有点奇怪。该方法基本上是使用 flatten
来轻松按我们想要的顺序对单元格进行分组,即每个位置一列。这让我们可以跨列映射以生成另一个向量,然后将该向量放回正确的矩阵中。可能需要对大于 2x2 的矩阵进行一些测试。
我想到的另一种方法是使用 cross
列出所有索引组合,然后类似于您的示例逐个单元格映射和创建矩阵单元格。如果需要可以尝试。
library(tidyverse)
z1 <- matrix(101:104, nrow = 2, ncol = 2)
z2 <- matrix(201:204, nrow = 2, ncol = 2)
z3 <- matrix(301:304, nrow = 2, ncol = 2)
z4 <- matrix(401:404, nrow = 2, ncol = 2)
z5 <- matrix(501:504, nrow = 2, ncol = 2)
z6 <- matrix(601:604, nrow = 2, ncol = 2)
z7 <- matrix(701:704, nrow = 2, ncol = 2)
z8 <- matrix(801:804, nrow = 2, ncol = 2)
z9 <- matrix(901:904, nrow = 2, ncol = 2)
z10 <- matrix(1001:1004, nrow = 2, ncol = 2)
# Combine all matrices into a single list
za <- list(z1, z2, z3, z4, z5, z6, z7, z8, z9, z10)
quant_mat <- function(list, p){
dim = ncol(list[[1]]) * nrow(list[[1]])
list %>%
flatten_int() %>%
matrix(ncol = dim, byrow = TRUE) %>%
as_tibble() %>%
map_dbl(quantile, probs = p) %>%
matrix(ncol = ncol(list[[1]]))
}
quant_mat(za, 0.975)
#> [,1] [,2]
#> [1,] 978.5 980.5
#> [2,] 979.5 981.5
quant_mat(za, 0.025)
#> [,1] [,2]
#> [1,] 123.5 125.5
#> [2,] 124.5 126.5
由 reprex package (v0.2.0) 创建于 2018-03-14。
这应该可以解决使用 tidyverse 的单个分位数的问题:
tibble(za) %>%
mutate(za = map(za, ~ data.frame(t(flatten_dbl(list(.)))))) %>%
unnest(za) %>%
summarize_all(quantile, probs = .975) %>%
matrix(ncol = 2)
我有以下 reprex
10 个样本矩阵的列表:
# Sample of 10 3*3 matrices
z1 <- matrix(101:104, nrow = 2, ncol = 2)
z2 <- matrix(201:204, nrow = 2, ncol = 2)
z3 <- matrix(301:304, nrow = 2, ncol = 2)
z4 <- matrix(401:404, nrow = 2, ncol = 2)
z5 <- matrix(501:504, nrow = 2, ncol = 2)
z6 <- matrix(601:604, nrow = 2, ncol = 2)
z7 <- matrix(701:704, nrow = 2, ncol = 2)
z8 <- matrix(801:804, nrow = 2, ncol = 2)
z9 <- matrix(901:904, nrow = 2, ncol = 2)
z10 <- matrix(1001:1004, nrow = 2, ncol = 2)
# Combine all matrices into a single list
za <- list(z1, z2, z3, z4, z5, z6, z7, z8, z9, z10)
我们想要的是将 za
作为输入并获得 2 2*2 matrices
称为 upper_quantile
和 lower_quantile
矩阵。
本质上,这是采用上面的 10 个矩阵列表,并为 对应的条目 取上 97.5% 的分位数。较低的 2.5% 分位数也是如此。
在这种情况下,我们可以手动构造此示例的upper_quantile
矩阵,如下所示:
upper_quantile <- matrix(data = c(quantile(x = seq(101, 1001, by = 100), probs = 0.975),
c(quantile(x = seq(102, 1002, by = 100), probs = 0.975)),
c(quantile(x = seq(103, 1003, by = 100), probs = 0.975)),
c(quantile(x = seq(104, 1004, by = 100), probs = 0.975)))
, nrow = 2
, ncol = 2
, byrow = FALSE)
upper_quantile
#> [,1] [,2]
#> [1,] 978.5 980.5
#> [2,] 979.5 981.5
我想了解如何使用 purrr
或 tidyverse
工具来做到这一点,因为我一直在努力避免列表上的繁琐循环,并希望自动调整尺寸。
有人可以帮忙吗?
这里有一个稍微笨拙的方法,它至少将所有内容都放在一个管道中。它假设所有矩阵都是相同的维度,这必须是真实的,否则所需的输出没有多大意义。在 purrr
中使用矩阵总是有点奇怪。该方法基本上是使用 flatten
来轻松按我们想要的顺序对单元格进行分组,即每个位置一列。这让我们可以跨列映射以生成另一个向量,然后将该向量放回正确的矩阵中。可能需要对大于 2x2 的矩阵进行一些测试。
我想到的另一种方法是使用 cross
列出所有索引组合,然后类似于您的示例逐个单元格映射和创建矩阵单元格。如果需要可以尝试。
library(tidyverse)
z1 <- matrix(101:104, nrow = 2, ncol = 2)
z2 <- matrix(201:204, nrow = 2, ncol = 2)
z3 <- matrix(301:304, nrow = 2, ncol = 2)
z4 <- matrix(401:404, nrow = 2, ncol = 2)
z5 <- matrix(501:504, nrow = 2, ncol = 2)
z6 <- matrix(601:604, nrow = 2, ncol = 2)
z7 <- matrix(701:704, nrow = 2, ncol = 2)
z8 <- matrix(801:804, nrow = 2, ncol = 2)
z9 <- matrix(901:904, nrow = 2, ncol = 2)
z10 <- matrix(1001:1004, nrow = 2, ncol = 2)
# Combine all matrices into a single list
za <- list(z1, z2, z3, z4, z5, z6, z7, z8, z9, z10)
quant_mat <- function(list, p){
dim = ncol(list[[1]]) * nrow(list[[1]])
list %>%
flatten_int() %>%
matrix(ncol = dim, byrow = TRUE) %>%
as_tibble() %>%
map_dbl(quantile, probs = p) %>%
matrix(ncol = ncol(list[[1]]))
}
quant_mat(za, 0.975)
#> [,1] [,2]
#> [1,] 978.5 980.5
#> [2,] 979.5 981.5
quant_mat(za, 0.025)
#> [,1] [,2]
#> [1,] 123.5 125.5
#> [2,] 124.5 126.5
由 reprex package (v0.2.0) 创建于 2018-03-14。
这应该可以解决使用 tidyverse 的单个分位数的问题:
tibble(za) %>%
mutate(za = map(za, ~ data.frame(t(flatten_dbl(list(.)))))) %>%
unnest(za) %>%
summarize_all(quantile, probs = .975) %>%
matrix(ncol = 2)