我有一个有三千行的df,我想创建一个带有零或一列的新列,具体取决于用不同的一行写的字。
我有一个功能来评估列中的条目,如果它匹配我正在寻找的单词,那么" 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)
但当然这不起作用,因为逻辑运算符只能用于数值。有谁知道如何做到这一点??
答案 0 :(得分:2)
您不能在字符上使用逻辑运算符,但是,您可以在逻辑语句中使用它们。您的if
语句应如下所示:
oneorzero <- function(x) {
if (x["col_one"] == "dog" | x["col_one"] =="cat" | x["col_one"] =="rat") {
return("1")
}
return("0")
}
此外,还有一个名为if
的{{1}}语句的矢量化版本。它可以使您的代码更简洁易读:
ifelse
答案 1 :(得分:2)
使用向量化和%in%
函数(请参阅help("%in%")
,但它应该是不言自明的):
as.integer(x["col_one"] %in% c("dog", "cat", "rat"))
as.integer
将逻辑值转换为0/1。
答案 2 :(得分:2)
在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