这是我昨天问的一个问题: Partial string match two columns R
提供的答案很棒;然而,我发现许多物种也没有被直接引用,即乌龟从来没有在dats $ product.authorise中直接描述,但是“异国情调”#39;是一个可以接受的比赛。
dats<-data.frame(ID=c(1:4),species=c("dog","cat","rabbit","tortoise"),
species.descriptor=c("all animal dog","all animal cat","rabbit exotic","tortoise exotic"),
product=c(1,2,3,4),product.authorise=c("all animal dog cat rabbit","cat horse pig",
"dog cat","exotic"))
dats
ID species species.descriptor product product.authorise
1 dog all animal dog 1 all animal dog cat rabbit
2 cat all animal cat 2 cat horse pig
3 rabbit rabbit exotic 3 dog cat
4 tortoise tortoise exotic 4 exotic
我提出了一个解决方案,它基于将$ species.descriptor和$ product.authorise绑定在一起,然后将该行指定为&#39; TRUE&#39;如果特定的reg exp在字段中出现两次或多次,如下所示:
library(stringr)
dats$bound<-paste(dats$product.authorise, dats$species.descriptor)
species_descriptor<-c("all animal","dog","cat","rabbit","exotic","horse","pig","tortoise")
species_descriptor<-setNames(nm=species_descriptor)
result<-ifelse(sapply(species_descriptor, str_count, string=dats$bound)>=2,"TRUE","FALSE")
result<-as.data.frame(result)
result$AuthorisedCount<-apply(result[,1:ncol(result)],MARGIN=1,function(x){sum(x=="TRUE",na.rm=T)})
result$SpeciesAuthorised<-ifelse(result$AuthorisedCount>=1,"TRUE","FALSE")
dats<-cbind(dats, result$SpeciesAuthorised)
names(dats)[7]<-"SpeciesAuthorised"
dats$bound<-NULL
dats
ID species species.descriptor product product.authorise SpeciesAuthorised
1 dog all animal dog 1 all animal dog cat rabbit TRUE
2 cat all animal cat 2 cat horse pig TRUE
3 rabbit rabbit exotic 3 dog cat FALSE
4 tortoise tortoise exotic 4 exotic TRUE
这很好,在更大的数据集上工作很快;但是,我知道可能有一种更优雅的做事方式。我想知道是否有人有任何建议?
答案 0 :(得分:2)
使用sapply
函数调用和bound
变量生成相同的结果:
bound<-paste(dats$product.authorise, dats$species.descriptor)
dats$SpeciesAuthorised <- as.logical(rowSums(sapply(species_descriptor, str_count, string=bound)>=2))
# ID species species.descriptor product product.authorise SpeciesAuthorised
# 1 1 dog all animal dog 1 all animal dog cat rabbit TRUE
# 2 2 cat all animal cat 2 cat horse pig TRUE
# 3 3 rabbit rabbit exotic 3 dog cat FALSE
# 4 4 tortoise tortoise exotic 4 exotic TRUE
答案 1 :(得分:1)
扩展你提到的帖子会有用吗?
neuePerson
我刚刚在函数中添加了一个OR运算符,以检测species.descriptor中product.authorise中的模式。
dats$SpeciesAuthorised <- with(dats,
str_detect(species.descriptor, species) &
(str_detect(product.authorise, species) | str_detect(species.descriptor,product.authorise))
)
答案 2 :(得分:1)
您可以使用函数any
:
bound <- paste(dats$product.authorise, dats$species.descriptor)
result <- ifelse(sapply(species_descriptor, str_count, string=bound)>=2, TRUE, FALSE)
dats$SpeciesAuthorised <- apply(result, 1, any)
无需将结果设置为"TRUE"
或"FALSE"
作为字符,使用逻辑。
此外,如果您想使代码更加干净和可读,您可以定义自己的功能:
isSpeciesAuthorised = function(data, species_descriptor) {
bound <- paste(data$product.authorise, data$species.descriptor)
result <- ifelse(sapply(species_descriptor, str_count, string=bound)>=2, TRUE, FALSE)
return(apply(result, 1, any))
}
然后使用它们:
dats$SpeciesAuthorised <- isSpeciesAuthorised(data=dats, species_descriptor)