Скалярная функция в R для мутата dplyr - PullRequest
0 голосов
/ 24 апреля 2020

Я хотел бы рассчитать двухпропорциональный критерий для четырех человек в R.

> example <- data.frame(x = 41:44, y = 43:46, z = c(100,100,100,100), w = c(101,101,101,101))
> example
   x  y   z   w
1 41 43 100 101
2 42 44 100 101
3 43 45 100 101
4 44 46 100 101

В частности, я хотел бы получить значение p из функции prop.test

> prop.test(c(41,43), c(100,101))$p.value
[1] 0.9336564

добавлено к каждой строке. Я хотел бы продолжить использовать функцию mutate из dplyr, которая позволяет мне легко делать такие вещи:

> example %>% mutate(total = x + y + z + w)
   x  y   z   w total
1 41 43 100 101   285
2 42 44 100 101   287
3 43 45 100 101   289
4 44 46 100 101   291

Однако это не делает то, что я ожидал для векторизованных функций, таких как sum().

> example %>% mutate(total = sum(x,y,z,w))
   x  y   z   w total
1 41 43 100 101  1152
2 42 44 100 101  1152
3 43 45 100 101  1152
4 44 46 100 101  1152
> example %>% mutate(just_z = sum(z))
   x  y   z   w just_z
1 41 43 100 101    400
2 42 44 100 101    400
3 43 45 100 101    400
4 44 46 100 101    400

Как показано, векторизованная функция sum() берет весь столбец z вместо чтения только значения z в соответствующей строке. В результате, prop.test, который я пытался запустить, дает неожиданный результат:

> example %>% mutate(p = prop.test(c(x,y), c(z,w))$p.value)
   x  y   z   w         p
1 41 43 100 101 0.9989672
2 42 44 100 101 0.9989672
3 43 45 100 101 0.9989672
4 44 46 100 101 0.9989672

Я могу получить свой ответ с некоторым отвратительным процедурным программированием или пониманием списка:

> to_vec(for(i in 1:length(example))
+     prop.test(c(example$x[i], example$y[i]),
+               c(example$z[i], example$w[i]))$p.value)
[1] 0.9336564 0.9349922 0.9362936 0.9375628

но этот подход не элегантен. Есть ли способ «скаляризовать» векторизованную функцию или иным образом, чтобы mutate работал только с элементами строки?

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Это проще с apply из base R, и эти построчные функции имеют незначительную разницу в эффективности при загрузке внешних пакетов

apply(example, 1, function(x) prop.test(x[1:2], x[3:4])$p.value)
#[1] 0.9336564 0.9349922 0.9362936 0.9375628
1 голос
/ 24 апреля 2020

Для таких операций вы можете использовать rowwise:

library(dplyr)
example %>% rowwise() %>% mutate(p = prop.test(c(x,y), c(z,w))$p.value)

#      x     y     z     w     p
#  <int> <int> <dbl> <dbl> <dbl>
#1    41    43   100   101 0.934
#2    42    44   100   101 0.935
#3    43    45   100   101 0.936
#4    44    46   100   101 0.938

или pmap варианты из purrr.

example %>% mutate(p = purrr::pmap_dbl(., 
               ~{x <- c(...);prop.test(x[1:2], x[3:4])$p.value}))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...