我想创建一个矩阵列表列,其中每个矩阵的条目都是原始数据集中已存在的变量的元素。我的目标是为数据集的每一行创建 2 x 2 列联表,然后将每个矩阵作为参数传递给 fisher.test
。
我尝试使用 mutate
和 matrix
的组合添加新列,但这会返回错误。我还尝试使用 do
而不是 mutate
,这似乎是朝着正确方向迈出的一步,但我知道这也是不正确的,因为元素的尺寸是关闭,并且输出中只有一行。
library(tidyverse)
mtcars %>%
mutate(mat = matrix(c(.$disp, .$hp, .$gear, .$carb)))
#> Error: Column `mat` must be length 32 (the number of rows) or one, not 128
mtcars %>%
do(mat = matrix(c(.$disp, .$hp, .$gear, .$carb)))
#> # A tibble: 1 x 1
#> mat
#> <list>
#> 1 <dbl [128 x 1]>
由 reprex package 创建于 2019-06-05 (v0.2.1)
我期望输出中有 32 行,并且 mat
列包含 32 个 2x2 矩阵,这些矩阵由来自 mtcars$disp
、mtcars$hp< 的条目组成
、mtcars$gear
和 mtcars$carb
。
我的目的是使用 map
将 mat
列中的每个条目作为参数传递给 fisher.test
,然后提取赔率比率估计值和 p 值。但当然,主要焦点是矩阵列表的创建。
最佳答案
您有两个问题:
- 要将矩阵存储在 data.frame (tibble) 中,您只需将其放入列表中即可。
- 要创建 2 x 2 矩阵(而不是在每个单元格中重复相同的 4 x 32 矩阵),您需要逐行工作。目前,当您执行 Matrix(c(disp, hp, gear, carb)) 时,您会创建一个 4 x 32 矩阵!您只需要 4 x 1 输入,并将其 reshape 为 2 x 2。
使用 pmap
可以让您逐行处理行,但您也可以使用按行分组的 rowwise
:
library(tidyverse)
df <-
mtcars %>%
as_tibble() %>%
rowwise() %>%
mutate(mat = list(matrix(c(disp, hp, gear, carb), 2, 2)))
编辑:现在你如何实际使用它们?让我们以fisher.test
为例。请注意,测试是一个复杂的对象,具有组件(如 p.value)和属性,因此我们必须将它们存储在列表列中。
您可以继续按行工作,在这种情况下,列表会自动“取消列出”:
df %>%
# keep in mind df is still grouped by row so 'mat' is only one matrix.
# A test is a complex object so we need to store it in a list-column
mutate(test = list(fisher.test(mat)),
# test is just one test so we can extract p-value directly
pval = test$p.value)
或者,如果您停止逐行工作(为此,您只需取消分组
),则 mat
是一个可以将函数映射到的矩阵列表。我们使用 purrr
中的 map
函数。
library("purrr")
df %>%
ungroup() %>%
# Apply the test to each mat using `map` from `purrr`
# `map` returns a list so `test` is a list-column
mutate(test = map(mat, fisher.test),
# Now `test` is a list of tests... so you need to map operations onto it
# Extract the p-values from each test, into a numeric column rather than a list-column
pval = map_dbl(test, pluck, "p.value"))
您更喜欢哪一个取决于品味:)
关于r - 创建一列包含矩阵的 data.frames,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56478279/