我有两个顶级组和多个子组的年度值数据框架。我需要在每个子群中过滤掉公共周期之外的年份,这样我只剩下每个子群中两个顶级群之间的公共周期。
换句话说,我的数据帧是这样的:
Group Subgroup Year
A 1 1901
A 1 1902
A 1 1903
A 1 1904
B 1 1902
B 1 1903
B 1 1904
B 1 1905
但我需要它看起来像这样:
Group Subgroup Year
A 1 1902
A 1 1903
A 1 1904
B 1 1902
B 1 1903
B 1 1904
我还有一个数据帧(下面命名为"年"(,它具有每个子组的年范围:
Subgroup GroupA_Min GroupA_Max GroupB_Min GroupB_Max
1 1901 1904 1902 1905
我最初的方法包括在for循环中使用if/else语句(这里简化为一个条件(:
df_trimmed = data.frame(matrix())
for s in unique(df$subgroup){
subgroup = df[df$subgroup == s,]
selector = year[s, ]
if (selector$GroupA_Min < selector GroupB_Min & selector$GroupA_Max < selector$GroupB_Max{
subgroup = subset(subgroup, Year >= selector$GroupB_Min & Year <= selector$GroupA_Max)
df_trimmed = rbind(df_trimmed, subgroup)
然而,这并没有在小组中产生正确的公共时期,所以我想知道是否有更好的方法,或者我是否遗漏了一些东西。
IIUC,您希望在每个子组中的组A和组B之间共享年份。要获得此结果,请按子组对数据进行分组,然后选择两组中出现的年份。像这样:
library(dplyr)
df %>%
group_by(sub_group) %>%
filter(year %in% year[group == "A"],
year %in% year[group == "B"])
示例数据(包括sub_group
的两个值(:
set.seed(111)
n <- 16
df <- tibble(group = sample(c("A", "B"), size = n, replace = TRUE),
sub_group = sample(1:2, size = n, replace = TRUE),
year = c(1901:1908, 1902:1909)) %>%
arrange(sub_group, group, year)
你可以试试这个。对于每个Year
和Subgroup
组合,过滤以包括其中Year
的不同Group
的数目等于整个数据帧的不同Group
的数目。
library(dplyr)
df %>%
group_by(Year, Subgroup) %>%
filter(n_distinct(Group) == n_distinct(.$Group))
输出
Group Subgroup Year
<chr> <int> <int>
1 A 1 1902
2 A 1 1903
3 A 1 1904
4 B 1 1902
5 B 1 1903
6 B 1 1904
在我看来,您正在寻找类似dplyr::filter
的东西,使用dplyr::between
作为年份列?
您的数据
df <-
read.delim(text="Group Subgroup Year
A 1 1901
A 1 1902
A 1 1903
A 1 1904
B 1 1902
B 1 1903
B 1 1904
B 1 1905") %>% tidyr::separate("Group.Subgroup.Year",
into=c("Group", "Subgrouop", "Year"), sep=" ")
df %>% filter(between(Year, 1902, 1905))
产生
Group Subgrouop Year
1 A 1 1902
2 A 1 1903
3 A 1 1904
4 B 1 1902
5 B 1 1903
6 B 1 1904
7 B 1 1905
如果你想通过编程获得1902和1905的值,你可以这样做:
df %>%
group_by(Group) %>%
summarise(min_year = min(Year),
max_year = max(Year)) %>%
ungroup() %>%
summarise(from = max(min_year),
to = min(max_year)) -> ranges
# now use filter with
filter(df, Year, ranges$from, ranges$to)