有条件地仅更改数据框中的某些单元格 - ifelse() 失败?

Conditionally changing only some cells in a data frame - ifelse() failure?

我正在尝试在清理调查数据时有条件地更改一些项目。

我有两个问题,问题 X 和问题 Y。如果他们对问题 X 的回答是 1 或 2,他们会继续回答问题 Y。如果他们对问题 X 的回答是 3 或 4,他们会跳过问题 Y .

如果他们用 1 或 2 回答 X 然后跳过 Y,我想将他们的 'NULL!' 条目记录为 NA - 他们只是没有在应该回答的时候回答问题。 如果他们用 3 或 4 回答 X 然后跳过 Y,我想将他们的 'NULL!' 条目记录为 0 - 他们不应该回答问题,所以他们没有。

这是我制作的可重现数据集:

  set.seed(1)
df <- data.frame(
  X = as.factor(sample(c("1.00", "2.00", "3.00", "4.00"), 10, replace = TRUE)),
  Y = as.factor(sample(c("1.00", "2.00", "#NULL!"), 10, replace = TRUE))
)
df

我正在尝试分别用 NA 或 0 替换上述 'NULL!' 字段。我一直在用 ifelse() 尝试它,但运气不佳 - 它似乎 return 任何 1.00 或 2.00 为 NA 和 3.00 或 4.00 为 0 的东西。有没有更好的方法来做到这一点?我究竟做错了什么?

levels(df$Y) <- c(levels(df$Y), 0)
    df$Y <- ifelse(df$X == '3.00'| df$X == '4.00', df$Y[df$y == 'NULL!'] <- 0, df$Y[df$Y == '#NULL!'] <- NA)
    df

感谢您的帮助!

这个怎么样?

set.seed(1)

df <- data.frame(
  X = as.factor(sample(c("1.00", "2.00", "3.00", "4.00"), 10, replace = TRUE)),
  Y = as.factor(sample(c("1.00", "2.00", "#NULL!"), 10, replace = TRUE))
)

df$X <- as.character(df$X)
df$Y <- as.character(df$Y)

df$Y <- ifelse(df$X=="1.00" | df$X=="2.00" & df$Y == "#NULL!", NA, df$Y)

df$Y <- ifelse(df$X=="3.00" | df$X=="4.00", "0.00", df$Y)
df

      X    Y
1  2.00 1.00
2  2.00 1.00
3  3.00 0.00
4  4.00 0.00
5  1.00 <NA>
6  4.00 0.00
7  4.00 0.00
8  3.00 0.00
9  3.00 0.00
10 1.00 <NA>

您正在以艰难的方式做几件事。首先,使用因子限制一个人只能使用特定因子中存在的水平,这可能不是您想要的。其次,你有水平的“#NULL!”但正在尝试(未成功)测试 "NULL!" 的水平。我猜你希望他们处于同一水平。第三;您试图在 ifelse 的第二个和第三个参数中使用“<-”。这不会以您预期的方式成功。 ifelse.

不计算此类表达式的 LHS

您可以改为使用嵌套 ifelse:

df$Y <- ifelse( (df$X == '3.00'| df$X == '4.00') & df$Y == "#NULL!", 0,  
                     ifelse( df$Y == "#NULL!", NA, df$Y) ) # only mess with "Nulls"

df
      X    Y
1  2.00 1.00
2  2.00 1.00
3  3.00    0
4  4.00 2.00
5  1.00 <NA>
6  4.00 2.00
7  4.00    0
8  3.00    0
9  3.00 2.00
10 1.00 <NA>

为了防止您通过添加“0”级别处理的缺失级别问题,我制作了包含字符向量的数据框:

set.seed(1)
 df <- data.frame(X = sample(c("1.00", "2.00", "3.00", "4.00"), 10, replace== TRUE),
                  Y = sample(c("1.00", "2.00", "#NULL!"), 10, replace = TRUE),
                  stringsAsFactors=FALSE)

较早的 tidyverse 代码:

library(tidyverse)

df %>% mutate(Y = case_when(
  X == "3.00" ~ "0",
  X == "4.00" ~ "0",
  TRUE ~ as.character(Y)))