子集数据框基于多行中的重复值

B. *_*vis 2 r dplyr

我如何对下面的数据框进行子集化,以便仅显示列的列AAA:CCC都具有相同的值并保留IndID字段?

Dat <- data.frame(IndID = LETTERS[seq(1,10)],
                  AAA = c(1,5,3,2,3,1,5,4,6,2),
                  BBB = c(1,8,5,2,5,4,8,4,4,5),
                  CCC = c(1,5,3,2,3,5,5,4,6,5))

> Dat
   IndID AAA BBB CCC
1      A   1   1   1
2      B   5   8   5
3      C   3   5   3
4      D   2   2   2
5      E   3   5   3
6      F   1   4   5
7      G   5   8   5
8      H   4   4   4
9      I   6   4   6
10     J   2   5   5
Run Code Online (Sandbox Code Playgroud)

我想返回以下结果.

Result <- data.frame(IndID = c("A", "D", "H"),
                  AAA = c(1,2,4),
                  BBB = c(1,2,4),
                  CCC = c(1,2,4))

> Result
  IndID AAA BBB CCC
1     A   1   1   1
2     D   2   2   2
3     H   4   4   4
Run Code Online (Sandbox Code Playgroud)

我发现了许多相关的帖子,包括在R中的数据框中查找重复的行(基于2列)使用dplyr查找重复的元素等,但是无法使用三列重现所需的结果.例如,虽然关闭下面的代码显示所有distinct行,但是包含行的不希望的结果只有两个值相等.

Dat %>% distinct(AAA, BBB, CCC) 
Run Code Online (Sandbox Code Playgroud)

我怀疑解决方案涉及filter但不确定如何从上述示例获得所需结果.甲dplyr溶液是优选的.

此外, 我也想知道这是否适用于多种因素.例如,下面的数据包含一个IndID和三个日期存储为因子,是否可以通过允许因子或将因子更改为数值来产生类似的结果?

Dat <- structure(list(GenIndID = structure(c(1L, 2L, 6L, 7L, 3L, 4L, 
8L, 5L), .Label = c("BHS_601", "BHS_603", "BHS_604", "BHS_605", 
"BHS_631", "BHS_635", "BHS_636", "BHS_637"), class = "factor"), 
    CptrDate = structure(c(1L, 2L, 3L, 3L, 2L, 2L, 3L, 4L), .Label = c("2016-02-01", 
    "2016-02-02", "2016-02-04", "2016-12-11"), class = "factor"), 
    DtLastAlive = structure(c(2L, 2L, 1L, 1L, 2L, 2L, 1L, 3L), .Label = c("2016-02-04", 
    "2017-07-13", "2017-08-27"), class = "factor"), DtFnlFate = structure(c(2L, 
    2L, 1L, 1L, 2L, 2L, 1L, 3L), .Label = c("2016-02-04", "2017-07-13", 
    "2017-08-27"), class = "factor")), .Names = c("GenIndID", 
"CptrDate", "DtLastAlive", "DtFnlFate"), row.names = c(82L, 83L, 
224L, 225L, 84L, 85L, 226L, 360L), class = "data.frame")


> Dat
    GenIndID   CptrDate DtLastAlive  DtFnlFate
82   BHS_601 2016-02-01  2017-07-13 2017-07-13
83   BHS_603 2016-02-02  2017-07-13 2017-07-13
224  BHS_635 2016-02-04  2016-02-04 2016-02-04
225  BHS_636 2016-02-04  2016-02-04 2016-02-04
84   BHS_604 2016-02-02  2017-07-13 2017-07-13
85   BHS_605 2016-02-02  2017-07-13 2017-07-13
226  BHS_637 2016-02-04  2016-02-04 2016-02-04
360  BHS_631 2016-12-11  2017-08-27 2017-08-27
Run Code Online (Sandbox Code Playgroud)

期望的结果是

> Dat[c(3, 4, 7),]
    GenIndID   CptrDate DtLastAlive  DtFnlFate
224  BHS_635 2016-02-04  2016-02-04 2016-02-04
225  BHS_636 2016-02-04  2016-02-04 2016-02-04
226  BHS_637 2016-02-04  2016-02-04 2016-02-04
Run Code Online (Sandbox Code Playgroud)

avi*_*seR 6

这是另一个解决方案:applyall:

Dat[apply(Dat[,-1], 1, function(x) all(x==x[1])),]
Run Code Online (Sandbox Code Playgroud)

或者filter_at来自dplyr:

library(dplyr)
Dat %>% 
  filter_at(vars(AAA:CCC), all_vars(. == .data$AAA))
Run Code Online (Sandbox Code Playgroud)

结果:

  IndID AAA BBB CCC
1     A   1   1   1
4     D   2   2   2
8     H   4   4   4
Run Code Online (Sandbox Code Playgroud)

编辑:

作为对OP的附加示例的回应,该apply示例无论变量类型如何都可以工作.所以以下内容适用于新示例:

Dat[apply(Dat[,-1], 1, function(x) all(x==x[1])),]
Run Code Online (Sandbox Code Playgroud)

结果:

    GenIndID   CptrDate DtLastAlive  DtFnlFate
224  BHS_635 2016-02-04  2016-02-04 2016-02-04
225  BHS_636 2016-02-04  2016-02-04 2016-02-04
226  BHS_637 2016-02-04  2016-02-04 2016-02-04
Run Code Online (Sandbox Code Playgroud)

对于filter_at,但是,如果比较列factor的,一个需要先转换为character:

Dat %>% 
  filter_at(vars(-1), all_vars(as.character(.) == .data$CptrDate))
Run Code Online (Sandbox Code Playgroud)

请注意,您只需要转换.为字符,但不是.data$CptrDate因为可以使用字符来处理因子,而不能使用具有不同级别的其他因子.

另一种选择是:

Dat %>%
  mutate_at(vars(-1), as.character) %>%
  filter_at(vars(-1), all_vars(. == .data$CptrDate))
Run Code Online (Sandbox Code Playgroud)

结果:

  GenIndID   CptrDate DtLastAlive  DtFnlFate
1  BHS_635 2016-02-04  2016-02-04 2016-02-04
2  BHS_636 2016-02-04  2016-02-04 2016-02-04
3  BHS_637 2016-02-04  2016-02-04 2016-02-04
Run Code Online (Sandbox Code Playgroud)