处理条件列中的NA值:基于DataFrame生成新列any与both
解决NA值问题,生成目标DataFrame
嘿,我来帮你搞定这个包含NA值的DataFrame处理问题!你的需求很清晰:给原始的df添加any和both两列,同时要正确处理y列里的NA值,对吧?
先明确一下规则细节(完全匹配你要的结果):
any列:只要x或y(任意一个)是'Y'就返回'Y',其他情况(包括NA、'N')都返回'N'both列:必须x和y**同时都是'Y'**才返回'Y',只要有一个不是'Y'或者是NA,都返回'N'
这里的关键是R里的NA在逻辑判断里会“捣乱”——比如NA == 'Y'会返回NA,直接用|或&运算会得到NA值,而不是我们想要的'N',所以得先把NA当作非'Y'的情况来处理。
方法一:先把NA换成'N'再计算(最直观)
既然NA相当于非'Y',那我们直接用coalesce把y列的NA替换成'N',之后逻辑判断就简单易懂了:
library(dplyr) # 你的原始数据 df <- data.frame( x = c('N', 'Y', 'N', 'Y', 'N'), y = c(NA, 'N', 'Y', 'Y', 'N') ) # 生成目标df2 df2 <- df %>% mutate( # 临时列:把y里的NA替换成'N' y_clean = coalesce(y, 'N'), # 计算any列:x或y_clean是'Y'就返回'Y',否则'N' any = if_else(x == 'Y' | y_clean == 'Y', 'Y', 'N'), # 计算both列:x和y_clean都是'Y'才返回'Y',否则'N' both = if_else(x == 'Y' & y_clean == 'Y', 'Y', 'N') ) %>% # 删掉临时的y_clean列,保留原始y列 select(-y_clean) # 查看结果,完全符合你的要求! df2
运行后得到的结果和你想要的完全一致:
x y any both 1 N <NA> N N 2 Y N Y N 3 N Y Y N 4 Y Y Y Y 5 N N N N
方法二:直接在逻辑判断里处理NA(不用临时列)
如果你不想多生成一个临时列,也可以直接用case_when结合is.na来写紧凑的逻辑:
df2 <- df %>% mutate( any = case_when( # 只要x是'Y',或者y是'Y'且不是NA,就返回'Y' x == 'Y' | (y == 'Y' & !is.na(y)) ~ 'Y', # 其他所有情况(包括NA、'N')都返回'N' TRUE ~ 'N' ), both = case_when( # 必须x和y都明确是'Y'才返回'Y' x == 'Y' & y == 'Y' ~ 'Y', # 其他情况(有一个不是'Y',或者有NA)都返回'N' TRUE ~ 'N' ) )
这个方法的逻辑和第一种完全一致,只是写法更简洁,不需要额外的临时列。
为啥要这么处理NA?
给你补个小知识点:在R里,逻辑运算遇到NA会返回NA,比如'N' | NA的结果是NA,这会导致你的any列出现NA值,而不是你想要的'N'。所以我们必须显式把NA当作非'Y'的情况来处理,才能得到正确的结果。
内容的提问来源于stack exchange,提问作者user42485
相关产品推荐
相关产品推荐

