Вы можете сделать это с помощью dplyr, хотя это не обязательно так интуитивно понятно, как другие решения. Однако функция do()
будет работать. ПРИМЕЧАНИЕ. - Я изменил вашу функцию mn()
, чтобы присвоить имена возвращаемому вектору.
Вот справочная страница для do()
. Сложная часть - как передать объект с пометкой .$
.
library(dplyr)
g1 = data.frame (
gene = c( "a","a","a","a","b"),
value = c(1,200,3,5,0)
)
mn <- function (x){
return(c(median = median(x), mean = mean(x)))
}
g1 %>% group_by(gene) %>%
do(data.frame(t(mn(.$value)))) %>%
data.frame()
#> gene median mean
#> 1 a 4 52.25
#> 2 b 0 0.00
Создано в 2019-01-11 пакетом Представление (v0.2.1)
Не углубляясь в глубокое погружение между data.table
и dplyr
, вот временное сравнение между двумя решениями на порции данных умеренного размера:
library(data.table)
library(dplyr)
#function
mn <- function (x){
return(list(median = median(x), mean = mean(x)))
}
#bigger data
g1 = data.frame(
gene = gl(1e5, 1e2),
value = rnorm(1e8)
)
f_dt <- function() setDT(g1)[, mn(value), by = gene]
f_dp <- function() g1 %>% group_by(gene) %>% do(data.frame(t(mn(.$value)))) %>% data.frame()
system.time(f_dt())
#> user system elapsed
#> 11.00 1.53 15.35
system.time(f_dp())
#> user system elapsed
#> 38.09 0.37 39.94
Создано в 2019-01-11 пакетом Представить (v0.2.1)