用聚合在 R 中做子集很热吗?
Hot to do subset in R with aggregation?
我有一个包含 2 列的大型数据框(200000 行):group_id 和 user_id。一个用户可以属于多个组。我需要一个包含属于 3 个以上组的所有用户的 group_id、user_id 的结果数据框。
group_id user_id
100 1
101 1
102 1
103 1
101 2
103 2
在上面的示例中,在结果数据框中我将只获得前 4 行。
df <- structure(list(group_id = c(100L, 101L, 102L, 103L, 101L, 103L
), user_id = c(1L, 1L, 1L, 1L, 2L, 2L)), .Names = c("group_id",
"user_id"), class = "data.frame", row.names = c(NA, -6L))
"data.table" 包使这变得简单。如果df
是原始数据框,你可以做
library(data.table)
setDT(df)[, .SD[.N > 3], by = user_id]
# user_id group_id
# 1: 1 100
# 2: 1 101
# 3: 1 102
# 4: 1 103
.N
告诉我们每组有多少行(这里选择user_id
),.SD
选择所有列。所以 .SD[.N > 3]
为我们提供了超过三行的所有组。
注意:如果不想把原来的df
改成数据table,可以用as.data.table()
代替setDT()
。但是,这将复制 df
.
这是一个 dplyr 解决方案,但在看到@Richard 时我知道还有更好的 dplyr 方法:
library(dplyr)
df %>%
count(user_id) %>%
filter(n > 3) %>%
select(user_id) %>%
inner_join(df, .)
## Joining by: "user_id"
## group_id user_id
## 1 100 1
## 2 101 1
## 3 102 1
## 4 103 1
使用@Richard 的评论:
df %>%
group_by(user_id) %>%
filter(n() > 3)
假设 'group_id' 每个 'user_id' 都是唯一的,使用 base R
的选项将是
df[with(df, ave(user_id, user_id, FUN=length)>3),]
# group_id user_id
#1 100 1
#2 101 1
#3 102 1
#4 103 1
我有一个包含 2 列的大型数据框(200000 行):group_id 和 user_id。一个用户可以属于多个组。我需要一个包含属于 3 个以上组的所有用户的 group_id、user_id 的结果数据框。
group_id user_id
100 1
101 1
102 1
103 1
101 2
103 2
在上面的示例中,在结果数据框中我将只获得前 4 行。
df <- structure(list(group_id = c(100L, 101L, 102L, 103L, 101L, 103L
), user_id = c(1L, 1L, 1L, 1L, 2L, 2L)), .Names = c("group_id",
"user_id"), class = "data.frame", row.names = c(NA, -6L))
"data.table" 包使这变得简单。如果df
是原始数据框,你可以做
library(data.table)
setDT(df)[, .SD[.N > 3], by = user_id]
# user_id group_id
# 1: 1 100
# 2: 1 101
# 3: 1 102
# 4: 1 103
.N
告诉我们每组有多少行(这里选择user_id
),.SD
选择所有列。所以 .SD[.N > 3]
为我们提供了超过三行的所有组。
注意:如果不想把原来的df
改成数据table,可以用as.data.table()
代替setDT()
。但是,这将复制 df
.
这是一个 dplyr 解决方案,但在看到@Richard 时我知道还有更好的 dplyr 方法:
library(dplyr)
df %>%
count(user_id) %>%
filter(n > 3) %>%
select(user_id) %>%
inner_join(df, .)
## Joining by: "user_id"
## group_id user_id
## 1 100 1
## 2 101 1
## 3 102 1
## 4 103 1
使用@Richard 的评论:
df %>%
group_by(user_id) %>%
filter(n() > 3)
假设 'group_id' 每个 'user_id' 都是唯一的,使用 base R
的选项将是
df[with(df, ave(user_id, user_id, FUN=length)>3),]
# group_id user_id
#1 100 1
#2 101 1
#3 102 1
#4 103 1