首页 > 解决方案 > 用 NA 替换所有零列

问题描述

我在 R 中有以下数据框

library(dplyr)
 library(tidyr)

df= data.frame("ID"= c("A", "A", "A", "A", "B", "B", "B"), 
"A1"= c(0,0, 0, 0, 1,0,1), "B1"= c(1,0, 1,0, 0, 0, 0))

数据框如下所示

  ID A1 B1
1  A  0  1
2  A  0  0
3  A  0  1
4  A  0  0
5  B  1  0
6  B  0  0
7  B  1  0

我想获得以下数据框

   ID A1 B1
 1  A NA  1
 2  A NA  0
 3  A NA  1
 4  A NA  0
 5  B  1 NA
 6  B  0 NA
 7  B  1 NA

我试过下面的代码

df%>%group_by(ID)%>%
mutate(A1=case_when(sum(A1)==0~NA))%>%
mutate(B1=case_when(sum(B1)==0~NA))

这会将 A1 和 B1 完全转换为 NA 值。

我在这里请求一些帮助。

标签: rdplyrtidyrna

解决方案


我们可以group_by ID使用mutate_allreplace

library(dplyr)

df %>%
  group_by(ID) %>%
  mutate_all(~replace(., all(. == 0), NA))

# ID       A1    B1
#  <fct> <dbl> <dbl>
#1 A        NA     1
#2 A        NA     0
#3 A        NA     1
#4 A        NA     0
#5 B         1    NA
#6 B         0    NA
#7 B         1    NA

如果还有其他列,并且我们只想将其应用于我们可以使用的特定列mutate_at

df %>%
  group_by(ID) %>%
  mutate_at(vars(A1,B1), ~replace(., all(. == 0), NA))

使用case_when我们可以这样做

df %>%
  group_by(ID) %>%
  mutate_all(~case_when(all(. == 0) ~ NA_real_, TRUE ~ .))

OP 尝试中的问题是没有TRUE定义案例,case_when因此当没有条件匹配时,它NA默认返回。从?case_when

如果没有匹配的案例,则返回 NA。

因此,如果我们定义这种TRUE情况,它将按预期工作。此外,我们不应该检查,sum(A1)==0因为如果列中存在负值和正值(如 -2 ,+2),它们将加起来为 0,从而产生意想不到的结果。

df%>%
  group_by(ID) %>%
  mutate(A1 = case_when(all(A1 == 0) ~ NA_real_, TRUE ~ A1), 
         B1 = case_when(all(B1 == 0) ~ NA_real_, TRUE ~ B1))

推荐阅读