设置所有相同的值NA,groupwise和colwise

And*_*ico 2 r

我希望每个col和group出现的所有相等/相同值(唯一== 1)设置为NA:
如果每组和col我们至少有2个不同的值,我想保留它们全部.

难以解释.以下是一些示例数据:

代表.例:

ds <- data.frame()
for (i in 1:3) {
    for(ii in 1:3) {
        ds <- rbind(mtcars[i,1:4],ds)
    }
}
rownames(ds) <- NULL
ds[1,1] <- 1337;ds[2:3,3] <- 1337;ds[5,2] <- 1337;ds[8,1] <- 1337;
ds <- cbind(group=rep(1:3,each=3),ds,stringis=c("a","a","a","b","c","d","e","e","f"))
Run Code Online (Sandbox Code Playgroud)

看起来像:

> ds
  group    mpg  cyl disp  hp stringis
1     1 1337.0    4  108  93        a
2     1   22.8    4 1337  93        a
3     1   22.8    4 1337  93        a
4     2   21.0    6  160 110        b
5     2   21.0 1337  160 110        c
6     2   21.0    6  160 110        d
7     3   21.0    6  160 110        e
8     3 1337.0    6  160 110        e
9     3   21.0    6  160 110        f
> 
Run Code Online (Sandbox Code Playgroud)

所需的输出是:

> ds
  group    mpg  cyl disp  hp stringis
1     1 1337.0   NA  108  NA       NA
2     1   22.8   NA 1337  NA       NA
3     1   22.8   NA 1337  NA       NA
4     2     NA    6   NA  NA        b
5     2     NA 1337   NA  NA        c
6     2     NA    6   NA  NA        d
7     3   21.0   NA   NA  NA        e
8     3 1337.0   NA   NA  NA        e
9     3   21.0   NA   NA  NA        f
> 
Run Code Online (Sandbox Code Playgroud)

我认为我可以设法在tapply中使用sapply,但我认为应该有更好,更可读/更快的解决方案.

寻找一般解决方案.实际上,这些团体并不总是三重组等.

Sot*_*tos 6

这是一个想法,

f1 <- function(x) replace(x, length(unique(x)) == 1, NA) 

library(dplyr)

ds %>% 
 group_by(group) %>% 
 mutate_all(funs(f1))

#Source: local data frame [9 x 6]
#Groups: group [3]

#  group    mpg   cyl  disp    hp stringis
#  <int>  <dbl> <dbl> <dbl> <dbl>   <fctr>
#1     1 1337.0    NA   108    NA       NA
#2     1   22.8    NA  1337    NA       NA
#3     1   22.8    NA  1337    NA       NA
#4     2     NA     6    NA    NA        b
#5     2     NA  1337    NA    NA        c
#6     2     NA     6    NA    NA        d
#7     3   21.0    NA    NA    NA        e
#8     3 1337.0    NA    NA    NA        e
#9     3   21.0    NA    NA    NA        f
Run Code Online (Sandbox Code Playgroud)

或者如果您不想定义函数,那么

ds %>% 
 group_by(group) %>% 
 mutate_all(funs(replace(., length(unique(.)) == 1, NA)))
Run Code Online (Sandbox Code Playgroud)

data.table

library(data.table)
setDT(ds)[, lapply(.SD, f1), by = group][]

#   group    mpg  cyl disp hp stringis
#1:     1 1337.0   NA  108 NA       NA
#2:     1   22.8   NA 1337 NA       NA
#3:     1   22.8   NA 1337 NA       NA
#4:     2     NA    6   NA NA        b
#5:     2     NA 1337   NA NA        c
#6:     2     NA    6   NA NA        d
#7:     3   21.0   NA   NA NA        e
#8:     3 1337.0   NA   NA NA        e
#9:     3   21.0   NA   NA NA        f
Run Code Online (Sandbox Code Playgroud)

基地R.

ds[-1] <- lapply(ds[-1], function(i) with(ds, ave(i, group, FUN = f1)))

ds
#  group    mpg  cyl disp hp stringis
#1     1 1337.0   NA  108 NA     <NA>
#2     1   22.8   NA 1337 NA     <NA>
#3     1   22.8   NA 1337 NA     <NA>
#4     2     NA    6   NA NA        b
#5     2     NA 1337   NA NA        c
#6     2     NA    6   NA NA        d
#7     3   21.0   NA   NA NA        e
#8     3 1337.0   NA   NA NA        e
#9     3   21.0   NA   NA NA        f
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`n_distinct`使其成为dplyr语法或`unique.table`中的`uniqueN` (3认同)