Статистика начальной загрузки R по группам для больших данных

Я хочу загрузить набор данных, в котором есть группы. Простым сценарием будет загрузка простых средств:

data <- as.data.table(list(x1 = runif(200), x2 = runif(200), group = runif(200)>0.5))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2)), by = "group"]}
boot(data, stat, R = 10)

Это дает мне ошибку incorrect number of subscripts on matrix из-за части by = "group". Мне удалось решить это с помощью подмножества, но мне это решение не нравится. Есть ли более простой способ заставить эту задачу работать?

В частности, я хотел бы ввести дополнительный аргумент в функцию статистики, например stat(x, i, groupvar), и передать его функции загрузки, например boot(data, stat(groupvar = group), R = 100)?


person RInatM    schedule 20.09.2013    source источник
comment
Вы хотите сделать стратифицированную повторную выборку? В boot есть аргумент strata.   -  person Roland    schedule 20.09.2013
comment
нет, я просто хочу иметь отдельные значения статистики для каждой группы. Если я правильно понимаю, аргумент strata гарантирует, что ваша статистика НЕ ​​будет рассчитываться с использованием данных из одной группы, не так ли? Значение результата со стратами будет одномерным, вместо этого мне нужна статистика результатов n, где n - количество групп.   -  person RInatM    schedule 20.09.2013


Ответы (3)


Это должно сделать это:

data[, list(list(boot(.SD, stat, R = 10))), by = group]$V1
person eddi    schedule 20.09.2013
comment
Хорошо сделано. Я пытался сделать это с аргументом by data.table, но не смог понять. Хотите объяснить, почему list(list( необходимо? - person Ari B. Friedman; 20.09.2013
comment
@AriB.Friedman, вам нужен внутренний list, чтобы сообщить data.table, что вы сохраняете list в столбце (внешний list); может быть, data[, list(newcol = list(boot(... сделает это более понятным - person eddi; 20.09.2013
comment
@eddi Я обнаружил, что ваш ответ требует удаления by = group из предоставленной функции статистики OP ... подробнее см. В моем ответе. - person swihart; 20.04.2016

С использованием

 boot       * 1.3-18  2016-02-23 CRAN (R 3.2.3)                        
 data.table * 1.9.7   2015-10-05 Github (Rdatatable/data.table@d607425)

Я получил ошибку, используя код OP с ответом, предоставленным @eddi:

data <- as.data.table(list(x1 = runif(200), x2 = runif(200), group = runif(200)>0.5))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2)), by = "group"]}
data[, list(list(boot(.SD, stat, R = 10))), by = group]$V1

Выдает сообщение об ошибке:

Error in eval(expr, envir, enclos) : object 'group' not found 

Ошибка исправлена ​​удалением by=group из функции stat:

set.seed(1000)
data <- as.data.table(list(x1 = runif(200), x2 = runif(200), group = runif(200)>0.5))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2))]}
data[, list(list(boot(.SD, stat, R = 10))), by = group]$V1

Что дает следующие результаты статистики Bootstrap:

[[1]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
     original       bias    std. error
t1* 0.5158232  0.004930451  0.01576641
t2* 0.5240713 -0.001851889  0.02851483

[[2]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
     original        bias    std. error
t1* 0.5142383 -0.0072475030  0.02568692
t2* 0.5291694 -0.0001509404  0.02378447

Ниже я изменяю образец набора данных, чтобы выделить, какая статистика Bootstrap соответствует какой комбинации группы и столбца:

Рассмотрим группу 1, имеющую среднее значение 10 для x1 и среднее значение 10000 для x2, и группу 2, имеющую среднее значение 2000 для x1 и среднее значение 8000 для x2:

data2 <- as.data.table(list(x1 = c(runif(100, 9,11),runif(100, 1999,2001)), x2 = c(runif(100, 9999,10001),runif(100, 7999,8001)), group = rep(c(1,2), each=100)))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2))]}
data2[, list(list(boot(.SD, stat, R = 10))), by = group]$V1

Который дает:

[[1]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
      original       bias    std. error
t1*   10.00907  0.007115938  0.04349184
t2* 9999.90176 -0.019569568  0.06160653

[[2]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
    original       bias    std. error
t1* 1999.965  0.031694179  0.06561209
t2* 8000.110 -0.006569872  0.03992401
person swihart    schedule 20.04.2016

Много проблем в вашем коде, прежде чем вы даже доберетесь до части по группам.

Вы имели в виду что-то вроде этого?

data <- as.data.frame(list(x1 = runif(200), x2 = runif(200), group = factor(sample(letters[1:2]))))
stat <- function(x, i)  c(m1 = mean(x$x1[i]), m2 = mean(x$x2[i]))

> stat(x,1:10)
       m1        m2 
0.4465738 0.5522221 

Затем вы можете беспокоиться о том, чтобы выполнять это группой, как бы вы ни выбрали.

Например:

library(plyr)
dlply( data, .(group), function( dat ) boot(dat, stat, R=10) )

Для больших наборов данных попробуйте data.table:

by( seq(nrow(data)), data$group, function(idx) myboot(data[idx,]))

Я выбрал by(), а не аргумент ,by= data.table, потому что вы хотите, чтобы на выходе был список. Для этого могут быть какие-то функции, о которых я не знаю, но я не смог их найти (см. историю изменений для проблемы, которую это вызывало).

Подмножество по-прежнему выполняется с помощью метода [] data.table, так что это должно быть достаточно быстро.

person Ari B. Friedman    schedule 20.09.2013
comment
спасибо, это делает то, что я хочу. Но ссылка, которую вы разместили, рекомендует пакет data.table для подмножества и группировки больших наборов данных (в моем случае - 800 тысяч строк с 220 группами). Я все еще изо всех сил пытаюсь применить поднастройку data.table для вашего решения. - person RInatM; 20.09.2013
comment
@RInatM Вы не упомянули большие данные ;-). Я посмотрю, что я могу сделать, хотя я не эксперт по data.table. - person Ari B. Friedman; 20.09.2013
comment
@AriB.Friedman data[idx,] (где idx - номера строк) с data.table работает не быстрее, чем с data.frame. - person Matt Dowle; 20.09.2013
comment
@MatthewDowle .SD быстрее сделать, как в ответе Эдди? - person Ari B. Friedman; 20.09.2013
comment
@ AriB.Friedman Да, я этого и ожидал. Когда мы говорим, что .SD работает медленно, мы имеем в виду медленнее_, чем использование имен столбцов непосредственно в j. Но .SD намного быстрее, чем by(). - person Matt Dowle; 20.09.2013
comment
@MatthewDowle Будет ли в этом случае использование .I быстрее, чем .SD? - person Ari B. Friedman; 21.09.2013
comment
data[.I] создаст новую память для каждой группы (как это делают split и by), что сведет на нет преимущества группировки data.table. .SD выделяется один раз заранее для самой большой группы и повторно используется для каждой группы. Если используются все столбцы data, то рекомендуется .SD и как можно быстрее. - person Matt Dowle; 21.09.2013
comment
@MatthewDowle Приятно знать. Спасибо! - person Ari B. Friedman; 21.09.2013