如何使用dplyr获得相同的分组结果,以使结果与sqldf结果一致?
我尝试使用sqldf和dplyr实现SQL查询。 我需要使用这两个不同的库分别执行此操作。 不幸的是,我无法使用dplyr产生相同的结果如何使用dplyr获得相同的分组结果,以使结果与sqldf结果一致?,r,dplyr,grouping,sqldf,R,Dplyr,Grouping,Sqldf,我尝试使用sqldf和dplyr实现SQL查询。 我需要使用这两个不同的库分别执行此操作。 不幸的是,我无法使用dplyr产生相同的结果 library(sqldf) library(dplyr) Id <- c(1,2,3,4) HasPet <- c(0,0,1,1) Age <- c(20,1,14,10) Posts <- data.frame(Id, HasPet, Age) # sqldf way ref <- sqldf
library(sqldf)
library(dplyr)
Id <- c(1,2,3,4)
HasPet <- c(0,0,1,1)
Age <- c(20,1,14,10)
Posts <- data.frame(Id, HasPet, Age)
# sqldf way
ref <- sqldf("
SELECT Id, HasPet, MAX(Age) AS MaxAge
FROM Posts
GROUP BY HasPet
")
# dplyr way
res <- Posts %>%
group_by(HasPet) %>%
summarize(
Id,
HasPet,
MaxAge = max(Age)
) %>%
select(Id, HasPet, MaxAge)
head(ref)
head(res)
虽然sqldf的输出不同:
> head(res)
# A tibble: 4 x 3
# Groups: HasPet [2]
Id HasPet MaxAge
<dbl> <dbl> <dbl>
1 1 0 20
2 2 0 20
3 3 1 14
4 4 1 14
UPD。无法修改SQL查询。您的问题的答案是,SQL查询所做的事情与您的R代码版本不同。以下是等效的SQL查询: 选择Id、HasPet、MAXAge OVER PARTITION BY HasPet作为MAXAge 发帖 实际上,您当前的查询在技术上是无效的,因为它通过HasPet聚合,但选择了Id。您不清楚要选择哪个Id值。以下是原始查询的有效版本: 选择HasPet,MAXAge作为MAXAge 发帖 HasPet分组
此问题可通过以下方法解决:
slice(which.min(Id))
在分组和汇总函数调用之后
例如:
# dplyr way
res <- Posts %>%
group_by(HasPet) %>%
summarize(
Id,
HasPet,
MaxAge = max(Age)
) %>%
select(Id, HasPet, MaxAge) %>%
slice(which.min(Id))
在这种情况下,输出与使用dplyr相同:
> res
# A tibble: 2 x 3
# Groups: HasPet [2]
Id HasPet MaxAge
<dbl> <dbl> <dbl>
1 1 0 20
2 3 1 14
另外,我认为有更简单的方法,但到目前为止我还没有找到它们。代码没有错,但您试图实现的逻辑就是它。让我解释一下: 分组的预期输出包含Id=1,3。但是R怎么知道是这些而不是Id=2,4?。更具体地说,当您按HasPet=0进行分组时,R将选择Id的哪个值?1还是2?如果你没有给出具体的使用标准,R怎么知道呢?也就是说,这将提供您的预期输出:
res <- Posts %>%
group_by(HasPet) %>%
summarize(Id = min(Id),
MaxAge = max(Age))
谢谢你的回答!实际上,我的问题是如何获得与sqldf相同的行为,但使用dplyr。相反,您已经调整了sqldf的查询请求。我不知道原始SQL查询是否无效。我认为不是,因为它在执行时没有警告或错误。您试图匹配的SQL输出是由无效查询生成的。请解释如何选择Id值背后的逻辑。您确定此请求无效吗?与此特定查询相关的SQL文档中是否存在任何限制?据我所知,sqldf的最终结果生成的结果包含HasPet列中列出的经过过滤的重复值。我还发现,使用aggregate it not dplyr函数可以实现与sqldf相同的行为。看到我以前的评论有错误的网址。现在修好了。对不起,我同意你原来的SQL请求看起来很奇怪。不管怎样,它是有效的。我不确定sql查询在技术上是否无效。您希望从dplyr获得的确切输出是什么?为什么?@Tim Biegeleisen这是一些R课程要求的。我需要得到与sqldf产生的结果相同的结果,但是使用dplyr。这是通过测试的先决条件。请尝试:Posts%>%group\u byHasPet%>%slice\u minId%>%ungroup@G.Grothendieck使用LGTM,但您的变体具有不同的列名。它返回年龄列名,而不是必需的AgeMax。
res <- Posts %>%
group_by(HasPet) %>%
summarize(Id = min(Id),
MaxAge = max(Age))