根据组(行)和变量名称(列)将NA替换为0

时间:2019-01-29 16:44:30

标签: r

我的数据集很大,想替换很多NA,但不是全部。

在一组中,我想将所有NA替换为0。 在另一组中,我想将所有NA替换为0,但仅在不包含变量名称的特定部分的变量中使用,例如'b'

这里是一个例子:

group <- c(1,1,2,2,2)
abc <- c(1,NA,NA,NA,NA)
bcd <- c(2,1,NA,NA,NA)
cde <- c(5,NA,NA,1,2)
df <- data.frame(group,abc,bcd,cde)

  group abc bcd cde
1     1   1   2   5
2     1  NA   1  NA
3     2  NA  NA  NA
4     2  NA  NA   1
5     2  NA  NA   2

这就是我想要的:

  group abc bcd cde
1     1   1   2   5
2     1   0   1   0
3     2  NA  NA   0
4     2  NA  NA   1
5     2  NA  NA   2

这是我尝试过的:

#set 0 in first group: this works fine
df[is.na(df) & df$group==1] <- 0
#set 0 in second group but only if the variable name includes b: does not work
df[is.na(df) & df$group==2 & !grepl('b',colnames(df))] <- 0

dplyr解决方案以及基本解决方案都受到欢迎

3 个答案:

答案 0 :(得分:1)

对于第二组,使用j1 <- !grepl('b',colnames(df)) df[j1][df$group == 2 & is.na(df[j1])] <- 0 df # group abc bcd cde #1 1 1 2 5 #2 1 0 1 0 #3 2 NA NA 0 #4 2 NA NA 1 #5 2 NA NA 2 创建列索引,并在分配时使用它来对数据进行子集化

angular-cli.json

答案 1 :(得分:0)

或者,您可以使用:

library(dplyr)
df2 <- df %>% mutate_at(vars(names(df)[-1]),
         function(x) case_when((group==1 & is.na(x) ) ~ 0,
              (group==2 & is.na(x) & !grepl("b",deparse(substitute(x)))) ~ 0,
              TRUE ~ x))
> df2
  group abc bcd cde
1     1   1   2   5
2     1   0   1   0
3     2  NA  NA   0
4     2  NA  NA   1
5     2  NA  NA   2

答案 2 :(得分:0)

使用dplyr :: mutate_at也可以:

library(dplyr)

vars_mutate_1 <- names(df)[-1]
vars_mutate_2 <- grep(x = names(df)[-1], pattern = '^(?!.*b).*$', perl = TRUE, value = TRUE)

df %>% 
  mutate_at(.vars = vars_mutate_1, .funs = funs(if_else(group == 1 & is.na(.), 0, .))) %>%
  mutate_at(.vars = vars_mutate_2, .funs = funs(if_else(group == 2 & is.na(.), 0, .)))

  group abc bcd cde
1     1   1   2   5
2     1   0   1   0
3     2  NA  NA   0
4     2  NA  NA   1
5     2  NA  NA   2