使用基于group by的if语句替换NA值

时间:2018-03-12 15:35:46

标签: r

我希望在R中以更优雅的方式执行以下操作。我相信有一种方法,但只是无法绕过它。以下是问题。

我有一个包含NA的df。但是,我想将NA变为零,如果NA的总和不等于零,并且如果总和是NA,则保留为NA。下面的例子应该说清楚。

A<-c("A", "A", "A", "A", 
     "B","B","B","B",
     "C","C","C","C")
B<-c(1,NA,NA,1,NA,NA,NA,NA,2,1,2,3)
data<-data.frame(A,B)

以下是数据的外观

   A  B
1  A  1
2  A NA
3  A NA
4  A  1
5  B NA
6  B NA
7  B NA
8  B NA
9  C  2
10 C  1
11 C  2
12 C  3

我希望得到以下结果

   A  B
1  A  1
2  A  0
3  A  0
4  A  1
5  B NA
6  B NA
7  B NA
8  B NA
9  C  2
10 C  1
11 C  2
12 C  3

我知道我可以通过首先创建一个表来使用内连接,然后根据该表创建一个IF语句,但我想知道是否有办法在R中的一行或两行代码中执行它。

以下是与我所指的内部联接相关的解决方案

sum_NA <- function(x) if(all(is.na(x))) NA_integer_ else sum(x, na.rm=TRUE)

data2 <- data %>% group_by(A) %>% summarize(x = sum_NA(B), Y = 
ifelse(is.na(x), TRUE, FALSE))
data2

data2_1 <- right_join(data, data2, by = "A")

data <- mutate(data2_1, B = ifelse(Y == FALSE & is.na(B), 0,B))
data <- select(data, - Y,-x)
data

3 个答案:

答案 0 :(得分:4)

也许像这样的解决方案可行:

data[is.na(B) & A %in% unique(na.omit(data)$A), ]$B <- 0

你在这里问:

  • 如果BNA
  • 如果A在包含non-NA
  • 的字母内

然后制作这些值0

答案 1 :(得分:2)

或类似地,使用ifelse()

data$B <- ifelse(is.na(data$B) & data$A %in% unique(na.omit(data)$A), 0, data$B)

答案 2 :(得分:2)

dplyr

library(dplyr)
data %>%
  mutate(B=ifelse(is.na(B) & A %in% unique(na.omit(data)$A), 0, B))