0

我有一个包含两列的数据框,并且想要创建第三列,该列本质上是一个布尔值,用于判断第二列是否包含一组特定的指定值。

f <- data.frame(name=c("John", "Sara", "David", "Chad"),
                 car=c("Honda|Ford", "BMW", "Toyota|Chevy|Ford", 
                 "Toyota|Chevy|Ford|Honda"))

我做的第一件事是删除 | 从第二列中的每个字符串,并将这些值放在第三列中

library(stringr)
g = str_replace_all(f$car, "[^[:alnum:]]", " ")
f$make = c(g)
f

如果创建另一个列,我现在想要做什么,这将是一个布尔值,如果 make 包含一辆普通汽车,则为 1,如果它包含一辆不常见的汽车,则为 0。

common = c("Honda", "Ford", "Toyota", "Chevy")
not_common = c("BMW", "Lexus", "Acura")

我尝试了一些东西,包括 stringr 包和 ifelse 以产生以下输出。

   name                     car                    make       common   
1  John              Honda|Ford              Honda Ford           1
2  Sara                     BMW                     BMW           0
3 David       Toyota|Chevy|Ford       Toyota Chevy Ford           1
4  Chad Toyota|Chevy|Ford|Honda Toyota Chevy Ford Honda           1

由于可以将普通和不常见的汽车作为条目,因此不常见的 make 应该覆盖 common 并且该行应该在 common 列中取值 0。因此,如果一个条目同时包含 BMW 和 Ford,则该条目应在公共列中取 0。

任何人都可以帮助完成这项任务。

哦,这就是我尝试使用 stringr 包的方法,但它不起作用。

common = c("Honda", "Ford", "Toyota", "Chevy")
not_common = c("BMW", "Lexus", "Acura")
common_match <- str_c(common)
not_match <- str_c(not_common)

main <- function(df) {
  f$new_make <- str_detect(f$make, common_match)
  df
}

main(f)

谢谢!

4

2 回答 2

2

不确定这是否是最有效的方法,但请尝试使用grepifelse应用于f$car. 这些|字符仅or用于在内部组合搜索词grep,与数据中的分隔符无关。

f$common <- sapply(f$car,function(x) ifelse(length(grep("BMW|Lexus|Acura",x))>0,0,1))

结果:

> f
   name                     car common
1  John              Honda|Ford      1
2  Sara                     BMW      0
3 David       Toyota|Chevy|Ford      1
4  Chad Toyota|Chevy|Ford|Honda      1
于 2012-07-09T21:07:39.763 回答
2

另一种方法和比较

f2 <- f[rep(1:4,50000),]
system.time({
v <- sapply(f2$make, strsplit, " ")
sapply(v, function(x) max(1-not_common %in% x)*max(common %in% x))
})
 user  system elapsed 
 7.94    0.01    8.00 

system.time(sapply(f2$car,function(x) ifelse(length(grep("BMW|Lexus|Acura",x))>0,0,1)))
 user  system elapsed 
28.72    0.04   28.87 
于 2012-07-09T21:16:03.653 回答