我有一个大的DataFrame,看起来像这样:
ID GroupID a b ...
1 001 2 3
2 001 2 2
3 001 2 2
4 001 2 0
5 001 0 1
6 002 1 1
7 002 2 1
8 002 0 1
9 002 0 1
10 002 2 1
11 002 3 0
...
现在,当一个值出现在该组中超过75%时,我想将整个组设置为NA(因为我认为这些值是错误的)。
结果应如下所示:
ID GroupID a b ...
1 001 NA 3
2 001 NA 2
3 001 NA 2
4 001 NA 0
5 001 NA 1
6 002 1 NA
7 002 2 NA
8 002 0 NA
9 002 0 NA
10 002 2 NA
11 002 3 NA
...
我知道,这是一个非常具体的问题,但是也许您可以帮助我。
如果您需要上面的日期集:
ID <- c(1:11)
GroupID <- c('001','001','001','001','001','002','002','002','002','002','002')
a <- c(2,2,2,2,0,1,2,0,0,2,3)
b <- c(3,2,2,0,1,1,1,1,1,1,0)
DF <- data.frame(ID, GroupID, a,b)
答案 0 :(得分:2)
一种方法是
DF %>% group_by(GroupID) %>%
mutate_at(c("a", "b"), function(x) if(any(table(x) > length(x) * 0.75)) NA else x)
# A tibble: 11 x 4
# Groups: GroupID [2]
# ID GroupID a b
# <int> <fct> <dbl> <dbl>
# 1 1 001 NA 3
# 2 2 001 NA 2
# 3 3 001 NA 2
# 4 4 001 NA 0
# 5 5 001 NA 1
# 6 6 002 1 NA
# 7 7 002 2 NA
# 8 8 002 0 NA
# 9 9 002 0 NA
# 10 10 002 2 NA
# 11 11 002 3 NA
答案 1 :(得分:0)
我们还可以如下使用replace
。
library(dplyr)
anyPer <- function(x, threshold = 0.75){
a <- table(x)
b <- a/sum(a)
result <- any(b > threshold)
return(result)
}
dat2 <- dat %>%
group_by(GroupID) %>%
mutate_at(vars(-ID, -GroupID), funs(replace(., anyPer(.), NA))) %>%
ungroup()
dat2
# # A tibble: 11 x 4
# ID GroupID a b
# <int> <int> <int> <int>
# 1 1 1 NA 3
# 2 2 1 NA 2
# 3 3 1 NA 2
# 4 4 1 NA 0
# 5 5 1 NA 1
# 6 6 2 1 NA
# 7 7 2 2 NA
# 8 8 2 0 NA
# 9 9 2 0 NA
# 10 10 2 2 NA
# 11 11 2 3 NA
数据
dat <- read.table(text = "ID GroupID a b
1 001 2 3
2 001 2 2
3 001 2 2
4 001 2 0
5 001 0 1
6 002 1 1
7 002 2 1
8 002 0 1
9 002 0 1
10 002 2 1
11 002 3 0",
header = TRUE)