У меня есть два набора данных: 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 (), которая делает ее медленнее?

3
Werner 17 Апр 2019 в 01:54

2 ответа

Лучший ответ

С поддельными данными ниже, подведение итогов и объединение занимает около 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
3
eipi10 17 Апр 2019 в 15:14

Вот что делало это медленно: я не осознавал, что доход в 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 ()).

0
Werner 17 Апр 2019 в 15:25