在非空单元格条件下在数据框中创建新列

Creating new column in data frame with condition on nonempty cells

我有一个 table 看起来像这样:

  A   B
  aa  bb
  aa  
  aa  bb

我想检查数据框单元格是否为空白,如果是,则找到这样的结果 table:

  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}

'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] vs df$BB

我发现在大型 data.frames 和较慢的计算机上 ifelse() 有时会有点慢。因此,在您的情况下,一个简单的解决方法(因为您使用的是字符串)是:

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

根据jogo的评论编辑

你的循环有两个问题:(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