提取所有列组中常见的元素

时间:2017-07-28 16:34:52

标签: r

我有一个R数据集x如下:

  ID Month
1   1   Jan
2   3   Jan
3   4   Jan
4   6   Jan
5   6   Jan
6   9   Jan
7   2   Feb
8   4   Feb
9   6   Feb
10  8   Feb
11  9   Feb
12 10   Feb
13  1   Mar
14  3   Mar
15  4   Mar
16  6   Mar
17  7   Mar
18  9   Mar
19  2   Apr
20  4   Apr
21  6   Apr
22  7   Apr
23  8   Apr
24 10   Apr
25  1   May
26  2   May
27  4   May
28  6   May
29  7   May
30  8   May
31  2   Jun
32  4   Jun
33  5   Jun
34  6   Jun
35  9   Jun
36 10   Jun

我试图找出一个R函数/代码来识别每个月存在至少的所有ID。 在上述情况下,ID 4&所有月份都有6

由于

3 个答案:

答案 0 :(得分:6)

首先,将df$ID拆分为Month并使用intersect查找每个子组中常见的元素。

Reduce(intersect, split(df$ID, df$Month))
#[1] 4 6

如果要对相应的data.frame进行子集化,请执行

df[df$ID %in% Reduce(intersect, split(df$ID, df$Month)),]

答案 1 :(得分:4)

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(df1)),按'ID'分组,获取行索引(.I),其中唯一'Months'的数量等于整个数据集中唯一“月”的数量,并基于此

对数据进行子集化
library(data.table)
setDT(df1)[df1[, .I[uniqueN(Month) == uniqueN(df1$Month)], ID]$V1]
#    ID Month
# 1:  4   Jan
# 2:  4   Feb
# 3:  4   Mar
# 4:  4   Apr
# 5:  4   May
# 6:  4   Jun
# 7:  6   Jan
# 8:  6   Jan
# 9:  6   Feb
#10:  6   Mar
#11:  6   Apr
#12:  6   May
#13:  6   Jun

提取'ID

setDT(df1)[, ID[uniqueN(Month) == uniqueN(df1$Month)], ID]$V1
#[1] 4 6

base R

1)tablerowSums

一起使用
v1 <- rowSums(table(df1) > 0)
names(v1)[v1==max(v1)]
#[1] "4" "6"

此信息可用于数据的子集

subset(df1, ID %in% names(v1)[v1 == max(v1)])

2)使用tapply

lst <- with(df1, tapply(Month, ID, FUN = unique))
names(which(lengths(lst) == length(unique(df1$Month))))
#[1] "4" "6"

或使用dplyr

library(dplyr)
df1 %>%
     group_by(ID) %>%
     filter(n_distinct(Month)== n_distinct(df1$Month)) %>%
     .$ID %>%
     unique
#[1] 4 6

或者如果我们需要获取行

df1 %>%
     group_by(ID) %>%
     filter(n_distinct(Month)== n_distinct(df1$Month))
# A tibble: 13 x 2
# Groups:   ID [2]
#      ID Month
#   <int> <chr>
# 1     4   Jan
# 2     6   Jan
# 3     6   Jan
# 4     4   Feb
# 5     6   Feb
# 6     4   Mar
# 7     6   Mar
# 8     4   Apr
# 9     6   Apr
#10     4   May
#11     6   May
#12     4   Jun
#13     6   Jun

答案 2 :(得分:0)

使用 dplyrpurrr 的替代解决方案:

tib %>%
  dplyr::group_by(Month) %>%
  dplyr::group_split(.keep = F) %>%
  purrr::reduce(intersect)

# A tibble: 2 x 1
#      ID
#   <dbl>
# 1     4
# 2     6

返回所需的 ID,其中 tib 是包含输入数据的 tibble。