我如何对下面的数据框进行子集化,以便仅显示列的列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)
这是另一个解决方案:apply和all:
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)
| 归档时间: |
|
| 查看次数: |
797 次 |
| 最近记录: |