【发布时间】:2017-06-07 10:56:04
【问题描述】:
正如here 所解释的,当ifelse(test, yes, no) 中的测试条件为NA 时,评估也是NA。因此以下返回...
df <- data.frame(a = c(1, 1, NA, NA, NA ,NA),
b = c(NA, NA, 1, 1, NA, NA),
c = c(rep(NA, 4), 1, 1))
ifelse(df$a==1, "a==1",
ifelse(df$b==1, "b==1",
ifelse(df$c==1, "c==1", NA)))
#[1] "a==1" "a==1" NA NA NA NA
... 而不是想要的
#[1] "a==1" "a==1" "b==1" "b==1" "c==1" "c==1"
按照 Cath 的建议,我可以通过正式指定测试条件不应包含 NA 来规避此问题:
ifelse(df$a==1 & !is.na(df$a), "a==1",
ifelse(df$b==1 & !is.na(df$b), "b==1",
ifelse(df$c==1 & !is.na(df$c), "c==1", NA)))
但是,正如 akrun 还指出的那样,随着列数的增加,此解决方案变得相当冗长。
解决方法是首先将所有 NAs 替换为 data.frame 中不存在的值(例如,在本例中为 2):
df_noNA <- data.frame(a = c(1, 1, 2, 2, 2 ,2),
b = c(2, 2, 1, 1, 2, 2),
c = c(rep(2, 4), 1, 1))
ifelse(df_noNA$a==1, "a==1",
ifelse(df_noNA$b==1, "b==1",
ifelse(df_noNA$c==1, "c==1", NA)))
#[1] "a==1" "a==1" "b==1" "b==1" "c==1" "c==1"
但是,我想知道是否有更直接的方法来告诉ifelse 忽略 NAs?还是为& !is.na写一个函数是最直接的方式?
ignorena <- function(column) {
column ==1 & !is.na(column)
}
ifelse(ignorena(df$a), "a==1",
ifelse(ignorena(df$b), "b==1",
ifelse(ignorena(df$c), "c==1", NA)))
#[1] "a==1" "a==1" "b==1" "b==1" "c==1" "c==1"
【问题讨论】:
标签: r if-statement na