dplyr:按组汇总(sum)非常慢
我有两个数据集:dplyr:按组汇总(sum)非常慢,r,dplyr,R,Dplyr,我有两个数据集:inds(个人)和hhs(家庭) 我正在尝试将所有inds$income按UID(唯一ID)分组,并在hhs上创建一个新列,其中包含一个家庭中所有个人的收入总和。有些人没有任何收入,在这种情况下,他们的变量为“NA”。我使用的代码是: hhs <- left_join(hhs, inds %>% group_by(UID) %>% summarize(hhincome = sum(income, na.rm=TRUE))) 用上述代码计算平均值需要5秒钟。函数
inds
(个人)和hhs
(家庭)
我正在尝试将所有inds$income
按UID
(唯一ID)分组,并在hhs
上创建一个新列,其中包含一个家庭中所有个人的收入总和。有些人没有任何收入,在这种情况下,他们的变量为“NA”。我使用的代码是:
hhs <- left_join(hhs, inds %>% group_by(UID) %>% summarize(hhincome = sum(income, na.rm=TRUE)))
用上述代码计算平均值需要5秒钟。函数
sum()
是否有什么特别的地方使它变慢了?下面的数据是假的,在我的机器上,汇总和连接大约需要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)
这就是让它慢下来的原因:我没有意识到,
inds$income
有标签:
> 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).
>总目(inds$收入)
:收入
[1] 0 0 0 0 258000 0
标签:
值标签
99999998未知/缺失。
999999999牛(不在宇宙中)。
当我移除标签时(将列重新编码为.numeric())。是否
UID
是hhs
和inds
共同的唯一列名?您希望在连接的数据帧中包含多少行?我认为@eipi10的目的是这里没有指定by=
连接条件。如果您有多个公共列,但只有很少的唯一值,则可能会得到一个非常大的联接。@Werner-没有by=
变量的相同问题可能仍然适用。你能试试左键联接(hhs,inds%%>%…,by=“UID”)吗?我想评论中的每个人都建议你需要指定要联接的列,因为左键联接接受左键联接(x,y,by=…),因此,hhs%groupby(UID)%>%summary(hhincome=sum(income,na.rm=TRUE)),by=“UID”)
@Werner-由于我们没有您的数据,我们都在猜测。如果指定by=
无法解决此问题,则您的原始hhs
文件中可能存在重复的UID
值。请尝试length(unique(hhs$UID))
并确保它与nrow(hhs)
相同。如果不是的话,你可能会有问题。它也很慢,所以可能是我的数据结构的问题。不幸的是,我不能共享数据(数据太大了),所以让我看看是否能找出问题所在。无论如何,非常感谢你的回答!伙计,我想我知道了。inds$收入有标签。在我移除它们之后,它变得更快了!我也这么做了。我使用Difftime创建了一个变量,但我忘了将新变量更改为as.numeric。非常感谢。
Unit: seconds
expr min lq mean median uq max neval
join 1.924749 1.988773 2.722018 2.0063 2.068044 5.622223 5
> 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).