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

时间:2019-02-27 22:59:40

标签: r conditional

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

我有两个问题,问题X和问题Y。如果他们对问题X回答1或2,则继续回答问题Y。如果他们对问题X回答3或4,则跳过问题Y。< / p>

如果他们用1或2回答X,然后跳过Y,我想记录他们的“ NULL!”条目不适用-他们什么时候都没有回答问题。 如果他们用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

我正在尝试替换前面提到的“ NULL!”分别为NA或0的字段。我一直在尝试使用ifelse(),但是运气不佳-它似乎返回的值是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

谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

这个怎么样?

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>

答案 1 :(得分:1)

您正在艰难地做几件事。首先,使用因数限制只能使用特定因数中存在的级别,而这可能不是您想要的。其次,您具有“ #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)))