Условно изменяя только несколько ячеек во фрейме данных - сбой ifelse ()? - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь условно изменить некоторые элементы при очистке данных опроса.

У меня есть два вопроса, Вопрос X и Вопрос Y. Если они отвечают 1 или 2 на Вопрос X, они продолжают отвечать на Вопрос Y. Если они отвечают 3 или 4 на Вопрос X, они пропускают ВопросY.

Если они отвечают X на 1 или 2, а затем пропускают Y, я хочу записать их 'NULL!'Записи как NA - они просто не ответили на вопрос, когда они должны были.Если они отвечают X на 3 или 4, а затем пропускают 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 голосов
/ 28 февраля 2019

Вы делаете пару вещей трудным путем.Во-первых, использование факторов ограничивает использование только уровней, которые существуют в конкретном факторе, что может не соответствовать вашим ожиданиям.Во-вторых, у вас есть уровни "#NULL!"но пытаются (безуспешно) проверить уровень «NULL!».Я предполагаю, что вы хотели, чтобы они были на одном уровне.В третьих;Вы пытаетесь использовать «<-» во втором и третьем аргументах <code>ifelse.Это не удастся так, как вы хотели.LHS такого выражения не оценивается как ifelse.

. Вместо этого можно использовать вложенные 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)

Предыдущий код обратного хода:

library(tidyverse)

df %>% mutate(Y = case_when(
  X == "3.00" ~ "0",
  X == "4.00" ~ "0",
  TRUE ~ as.character(Y)))
0 голосов
/ 28 февраля 2019

Как насчет этого?

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>
...