Создание data.frames, где один столбец содержит матрицы - PullRequest
2 голосов
/ 06 июня 2019

Я хотел бы создать список столбцов матриц, где записи каждой матрицы являются элементами из переменных, уже присутствующих в исходном наборе данных.Моя цель состоит в том, чтобы создать 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]>

Создано в 2019-06-05 пакетом Представить (v0.2.1)

Я ожидаю 32 строки в моемвыходные данные и столбец mat, содержащий 32 матрицы 2x2, состоящие из записей из mtcars$disp, mtcars$hp, mtcars$gear и mtcars$carb.

Мое намерение состоит в том, чтобы использовать map для передачи каждой записи в столбце mat в качестве аргумента fisher.test, затем извлечь оценку отношения шансов и значение p.Но основной упор, конечно же, это создание списка матриц.

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

У вас есть две проблемы:

  • Чтобы сохранить матрицу в data.frame (tibble), вы просто должны поместить ее в список.
  • Чтобы создать 2 x2 матрицы (вместо того, чтобы повторять одну и ту же матрицу 4 x 32 в каждой ячейке), вам нужно работать строка за строкой.В настоящее время, когда вы делаете matrix(c(disp, hp, gear, carb)), вы создаете матрицу 4 x 32!Вам нужно только 4 x 1 входа, преобразованных в 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) и атрибутами, поэтому нам придется хранить их в столбце списка.

Вы можете продолжить работу rowwise, вв этом случае список автоматически "unlist-ed":

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)

или если вы перестанете работать построчно (для чего вам просто нужно ungroup), тогда mat - это список матрицна который вы можете отобразить функции.Мы используем map функции из purrr.

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"))

Какой из них вы предпочитаете - дело вкуса :)

2 голосов
/ 06 июня 2019

вы можете использовать функцию pmap из пакета purrr внутри mutate:

library(tidyverse)
mtcars %>% as_tibble() %>% 
  mutate(mat = pmap(list(disp, hp, gear, carb), ~matrix(c(..1, ..2, ..3, ..4), 2, 2)))

# A tibble: 32 x 12
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb mat              
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <list>           
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4 <dbl[,2] [2 x 2]>
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4 <dbl[,2] [2 x 2]>

Каждая запись мата - это матрица 2х2 с нужными элементами. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...