基于另一列创建一个新的数据框列
问题描述:
我有一个有两列的数据框,并且想要创建第三列,它本质上是一个布尔值,用于列2是否包含一组特定的值。基于另一列创建一个新的数据框列
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
我现在要怎么做,如果创建另一列,这将是一个布尔值,1如果make包含一个共同的汽车和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
因为它可能同时拥有常见和不常见的车作为入门,不凡的化妆应覆盖常见品牌和该行应采取值0的公共列。因此,如果一个条目同时包含宝马和福特,则该条目在共同栏中应该为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)
谢谢!
答
的另一种方法和比较
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
答
不确定这是否是最有效的方法,但试试这个使用grep
和ifelse
的方法应用于每个值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