为何R数据框中布尔表达式直接相加得布尔值,分步相加得整数?
为何R中直接相加布尔表达式得到布尔值,分步创建中间列却得到整数?
先看测试数据:
# 构造含缺失值的数据框 subjid <- c(101,102,103,104,105,106,107,108) var1 <- c(1,2,3,4,NaN,NaN,NaN,NaN) var2 <- c(1,2,NaN,NaN,5,6,NaN,NaN) var3 <- c(1,NaN,3,NaN,5,NaN,7,NaN) df <- data.frame(subjid, var1, var2, var3)
问题现象
- 一步计算时,试图通过相加三个布尔表达式计数非缺失值,结果得到布尔型列:
df$nonmissing_count_a <- !is.na(df$var1) + !is.na(df$var2) + !is.na(df$var3) table(df$nonmissing_count_a) # 输出: # FALSE TRUE # 5 3 - 分步创建中间布尔列再相加时,得到正确的整数计数:
df$var1_nonmissing <- !is.na(df$var1) df$var2_nonmissing <- !is.na(df$var2) df$var3_nonmissing <- !is.na(df$var3) df$nonmissing_count_b <- df$var1_nonmissing + df$var2_nonmissing + df$var3_nonmissing table(df$nonmissing_count_b) # 输出: # 0 1 2 3 # 1 3 3 1
核心原因
R中逻辑向量(TRUE/FALSE)参与算术运算时会临时转为整数(TRUE=1,FALSE=0),运算结果本应是整数向量。但直接赋值给数据框新列时,R的类型推断机制可能会将整数向量强制转回逻辑型——规则是整数大于0时转TRUE,等于0时转FALSE,这就出现了异常结果。
而分步操作时,先将布尔值存储为数据框的logical类型列,后续相加时R会明确将这些布尔列转为整数计算,并且将结果以integer类型保存到新列,因此得到正确的计数。
解决方法
方法1:显式转换为整数后相加
通过as.integer()强制将布尔表达式转为整数,避免类型自动转换:
df$nonmissing_count_c <- as.integer(!is.na(df$var1)) + as.integer(!is.na(df$var2)) + as.integer(!is.na(df$var3)) table(df$nonmissing_count_c)
方法2:使用rowSums()更简洁实现
rowSums()可以直接对每行的布尔值矩阵求和,自动处理类型转换:
# 选择需要计数的列,生成布尔矩阵后按行求和 df$nonmissing_count_d <- rowSums(!is.na(df[, c("var1", "var2", "var3")])) table(df$nonmissing_count_d)
两种方法都能直接得到整数类型的非缺失值计数结果。
内容的提问来源于stack exchange,提问作者David Miller
相关产品推荐
相关产品推荐

