Создание нового столбца во фрейме данных с условием о непустых ячейках

У меня есть таблица, выглядящая так:

  A   B
  aa  bb
  aa  
  aa  bb

И я хочу проверить, пуста ли ячейка фрейма данных, и если да, то найти таблицу результатов следующим образом:

  A  B  S
  aa bb bb
  aa    aa
  aa bb bb

Я использую этот код, но он не работает

for(k in dim(df))
  if (df$BB == ""){
    df$S <- df$AA
  }else {df$S <- df$BB}

person Student1000    schedule 26.02.2018    source источник
comment
Посмотрите на ifelse()   -  person jogo    schedule 26.02.2018
comment
моя проблема заключается в проверке символа 0 ячейки!!   -  person Student1000    schedule 26.02.2018
comment
Пожалуйста, используйте dput(df), чтобы показать свои данные. Поместите результат dput(df) в свой вопрос, т.е. отредактируйте свой вопрос: stackoverflow.com/posts/48989530/edit   -  person jogo    schedule 26.02.2018


Ответы (3)


'ifelse' - ваш друг здесь. Он векторизован, поэтому здесь нет необходимости в цикле.

df <- data.frame(A = c("aa","aa","aa"), B = c("bb","","bb"))
df$S <- ifelse(df$B == '', df$A, df$B) 

#   A  B  S
#1 aa bb bb
#2 aa    aa
#3 aa bb bb

Если вы хотите изменить свой код, это работает, но менее эффективно, чем вариант ifelse:

df$S = NA
for(k in 1:nrow(df)) df$S[k] <- if (df$B[k] == "") df$A[k] else df$B[k]

Обратите внимание на 1:nrow(df) вместо dim(df) и фиксированную индексацию (df$B[k] против df$BB)

person Ape    schedule 26.02.2018

В вашем цикле есть две проблемы: (1) вы зацикливаетесь на dim(df), который является вектором [3, 2], и (2) вы фактически не индексируете k внутри цикла. Вы можете исправить код, который у вас есть сейчас, следующим образом:

df = data.frame(
  AA = c("aa", "aa", "aa"),
  BB = c("bb", "", "bb"),
  stringsAsFactors = FALSE
)


for(k in 1:nrow(df)) {
  if (df$BB[k] == "") {
    df$S[k] <- df$AA[k]
  } else {
    df$S[k] <- df$BB[k]
  }
}

Однако, как указывали другие, ifelse более эффективен, и это хорошая функция, которую можно использовать для многих целей:

df$SS = ifelse(df$BB == "", df$AA, df$BB)
# > df
#   AA BB  S SS
# 1 aa bb bb bb
# 2 aa    aa aa
# 3 aa bb bb bb
person Ry Guy    schedule 26.02.2018

Я обнаружил, что на больших кадрах данных и на медленном компьютере ifelse() иногда немного тормозит. Итак, в вашем случае простым обходным путем (поскольку вы используете строки) будет:

df$S <- df$B
df$S[df$B==""] <- df$A[df$B==""]

отредактировано в соответствии с комментарием Джого

person yoland    schedule 26.02.2018
comment
О, да, извините. ты прав конечно - person yoland; 27.02.2018