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

У меня есть таблица, похожая на это:

  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}

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)

В вашем цикле есть две проблемы: (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

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

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

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

Другие вопросы по тегам