dplyr: суммирование по группе (сумма) очень медленно - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть два набора данных: inds (физические лица) и hhs (домашние хозяйства).

Я пытаюсь суммировать все доходы в долларах США, сгруппированные по UID (уникальному идентификатору), и создать новый столбец в чч с суммой дохода всех людей в домохозяйствах.Некоторые люди не имеют никакого дохода, и в этом случае у них есть «NA» для этой переменной.Код, который я использую:

hhs <- left_join(hhs, inds %>% group_by(UID) %>% summarize(hhincome = sum(income, na.rm=TRUE)))

Однако он очень медленный.inds имеет более 2 миллионов строк, hhs - около 550 000 строк.Я использовал dplyr для усреднения или подсчета аналогичных переменных в одних и тех же наборах данных, и обычно для этого требуется десять секунд или меньше.Что-то я делаю не так?Есть ли способ сделать это быстрее?

Редактировать: как я уже сказал, я использовал dplyer для получения средних значений домохозяйств без проблем с

hhs <- left_join(hhs, inds %>% filter(AGE > 2) %>% group_by(UID) %>% summarize(L_Bilingual = mean(Bilingual, na.rm=TRUE)))

Для расчета требуется 5 секундсредства с кодом выше.Есть ли что-то особенное в функции sum (), которая делает ее медленнее?

Ответы [ 2 ]

3 голосов
/ 17 апреля 2019

С поддельными данными ниже, подведение итогов и объединение занимает около 2 секунд на моем компьютере, который является новым Macbook Pro. Даже на более медленной машине это не должно занять больше, чем, может быть, 10 или 15 секунд. Возможно ли, что объединение создает намного больше строк, чем вы думаете? Если вы предоставите более подробную информацию о структуре ваших данных, мы можем более конкретно указать, что может быть не так.

library(tidyverse)
library(microbenchmark)

# Generate two data frames with only the UID column in common
set.seed(2)
hhs = data.frame(UID=1:550000, replicate(30, runif(550000))) %>% 
  set_names(c("UID", paste0("V",1:30)))
inds = data.frame(UID=sample(1:550000, 2e6, replace=TRUE), 
                  income=rnorm(2e6, 5e4, 1e4),
                  replicate(20, rnorm(2e6, 5e4, 1e4)))

microbenchmark(join=left_join(hhs, inds %>% group_by(UID) %>% 
                                summarize(hhincome = sum(income, na.rm=TRUE))),
               times=5)
Unit: seconds
 expr      min       lq     mean median       uq      max neval
 join 1.924749 1.988773 2.722018 2.0063 2.068044 5.622223     5
0 голосов
/ 17 апреля 2019

Вот что делало это медленно: я не понимал, что доход в inds $ имеет метки:

> head(inds$income)
<Labelled double>: Earned income
[1]      0      0      0      0 258000      0

Labels:
value                  label
 99999998       Unknown/missing.
 99999999 NIU (not in universe).

Проблема была устранена, когда я удалил метки (перекодировав столбец с помощью as.numeric ()).

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