对字符使用逻辑运算符

using logical operators with characters

我有一个包含 3000 行的 df,我想创建一个新列,其中包含 0 或 1,具体取决于不同列中所写的单词。

我有一个函数可以评估列中的条目,如果它与我要查找的词相匹配,则会在新列中返回“1”。像这样:

 oneorzero <- function(x) {
   if (x["col_one"] == "dog") {
     return("1")
   }
   return("0")
 }
 df["col_two"] = apply(df, 1, oneorzero)

我希望能够应用逻辑 OR 运算符,以便在遇到各种不同的单词时添加一个,如下所示:

 oneorzero <- function(x) {
   if (x["col_one"] == "dog" | "cat" | "rat") {
     return("1")
   }
   return("0")
 }
 df["col_two"] = apply(df, 1, oneorzero)

但这当然行不通,因为逻辑运算符只能用于数值。有谁知道如何做到这一点`?

您不能在字符上使用逻辑运算符,但是,您可以在逻辑语句上使用它们。您的 if 语句应如下所示:

 oneorzero <- function(x) {
   if (x["col_one"] == "dog" | x["col_one"] =="cat" | x["col_one"] =="rat") {
 return("1")
   }
   return("0")
 }

此外,还有一个 if 语句的向量化版本,称为 ifelse。它可以使您的代码更加简洁易读:

df["col_two"]=ifelse(df$col_one=="dog" | df$col_one=="cat" | df$col_one== "rat",1,0)

使用矢量化和 %in% 函数(参见 help("%in%"),但它应该是不言自明的):

as.integer(x["col_one"] %in% c("dog", "cat", "rat"))

as.integer 将逻辑值变为 0/1。

在 R 中使用矢量化解决方案然后循环总是更好。对于 3K 行的 data.frame 来说,这并不重要,但对于更大的行,您会发现性能有很大差异。

对于你的问题,我建议使用 grepl 函数。

# lets generate reproducible example
set.seed(321)
df <- data.frame(col_one = sapply(1:1e3, function(x) 
  paste(sample(c("dog", "cat", "fox", "rat", "bird", "car", "123"), 
               sample(1:7, 1), T), collapse = ",")) )

# how does it look like?
head(df, 10)
#                         col_one
# 1  123,cat,car,bird,rat,dog,fox
# 2               car,rat,cat,123
# 3                          bird
# 4                      bird,fox
# 5                  bird,rat,123
# 6  rat,123,car,bird,cat,dog,fox
# 7                      bird,123
# 8  bird,fox,rat,dog,car,cat,123
# 9                       rat,car
# 10     fox,dog,bird,car,rat,cat

df$col_01 <- +(grepl("dog|cat|rat", df$col_one))
#                          col_one col_01
# 1    123,cat,cat,fox,fox,rat,fox      1
# 2               car,bird,fox,car      0
# 3                           bird      0
# 4                       bird,fox      0
# 5                  bird,bird,123      0
# 6  rat,bird,car,123,rat,dog,bird      1
# 7                      bird,bird      0
# 8  bird,rat,car,dog,bird,rat,car      1
# 9                        rat,123      1
# 10       fox,dog,123,cat,cat,rat      1