将两个组的年度值的数据帧过滤到R中两个组和子组之间的公共周期



我有两个顶级组和多个子组的年度值数据框架。我需要在每个子群中过滤掉公共周期之外的年份,这样我只剩下每个子群中两个顶级群之间的公共周期。

换句话说,我的数据帧是这样的:

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)

你可以试试这个。对于每个YearSubgroup组合,过滤以包括其中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) 

最新更新