如何使用 dplyr 获得相同的分组结果以获得与 sqldf 结果一致的结果?
How to get same grouping results using dplyr to get result consistent with sqldf result?
我尝试使用 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("
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(ref)
Id HasPet MaxAge
1 1 0 20
2 3 1 14
而 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
更新。 SQL无法修改查询。
您的问题的答案是 SQL 查询 不是 做与您的 R 代码版本相同的事情。这是等效的 SQL 查询:
SELECT Id, HasPet, MAX(Age) OVER (PARTITION BY HasPet) AS MaxAge
FROM Posts
实际上,您当前的查询在技术上是无效的,因为它按 HasPet
聚合,但 select 是 Id
。不清楚 您想要 select Id
的哪个 值。这是原始查询的有效版本:
SELECT HasPet, MAX(Age) AS MaxAge
FROM Posts
GROUP BY HasPet
这个问题可以通过以下方式解决:
slice(which.min(Id))
在“group_by”和“汇总”函数调用之后。
例如:
# 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
P.S。我认为有更简单的方法,但目前我还没有找到。
代码没有错,但是你要实现的逻辑就是这样。让我解释一下:
您的分组预期输出包含 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 实现 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("
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(ref)
Id HasPet MaxAge
1 1 0 20
2 3 1 14
而 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
更新。 SQL无法修改查询。
您的问题的答案是 SQL 查询 不是 做与您的 R 代码版本相同的事情。这是等效的 SQL 查询:
SELECT Id, HasPet, MAX(Age) OVER (PARTITION BY HasPet) AS MaxAge
FROM Posts
实际上,您当前的查询在技术上是无效的,因为它按 HasPet
聚合,但 select 是 Id
。不清楚 您想要 select Id
的哪个 值。这是原始查询的有效版本:
SELECT HasPet, MAX(Age) AS MaxAge
FROM Posts
GROUP BY HasPet
这个问题可以通过以下方式解决:
slice(which.min(Id))
在“group_by”和“汇总”函数调用之后。
例如:
# 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
P.S。我认为有更简单的方法,但目前我还没有找到。
代码没有错,但是你要实现的逻辑就是这样。让我解释一下:
您的分组预期输出包含 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))