Цикл grepl () через данные.таблицы (R)
у меня есть набор данных, хранящихся в данных.таблица DT
это выглядит так:
print(DT)
category industry
1: administration admin
2: nurse practitioner truck
3: trucking truck
4: administration admin
5: warehousing nurse
6: warehousing admin
7: trucking truck
8: nurse practitioner nurse
9: nurse practitioner truck
Я хотел бы уменьшить таблицу только до строк, где отрасль соответствует категории. Мой общий подход-использовать grepl()
для регулярного выражения соответствует строке '^{{INDUSTRY}}[a-z ]+$'
и каждый ряд DT$category
, С каждой соответствующей строки DT$industry
вставить вместо {{INDUSTRY}}
в строке регулярного выражения с помощью infuse()
. Я изо всех сил пытался найти гладкие данные.решение таблицы, которое будет правильно проходить через таблицу и сделайте сравнения внутри строки, поэтому я прибегнул к for-loop, чтобы выполнить работу:
template <- "^{{IND}}[a-z ]+$"
DT[,match := FALSE,]
for (i in seq(1,length(DT$category))) {
ind <- DT[i]$industry
categ <- d.daily[i]$category
if (grepl(infuse(IND=ind,template),categ)){
DT[i]$match <- TRUE
}
}
DT<- DT[match==TRUE]
print(DT)
category industry
1: administration admin
2: trucking truck
3: administration admin
4: trucking truck
5: nurse practitioner nurse
тем не менее, я уверен, что это можно сделать лучше. Любые предложения о том, как я мог бы достичь этого результата, используя данные.функциональность пакета таблицы? Насколько я понимаю, в этом контексте подход, который использует пакет, вероятно, будет более эффективным, чем for-loop.
3 ответов
данные.таблица хороша в сгруппированных операциях; я думаю, что это может помочь, предполагая, что у вас много строк с той же отраслью:
DT[ DT[, .I[grep(industry, category)], by = industry]$V1 ]
использует текущая идиома для подстановки по группам, благодаря @eddi .
комментарии. это может помочь дальше:
Если у вас есть много строк с той же отраслевой категории комбо, попробуйте
by=.(industry,category)
.попробуйте что-то еще в место
grep
(как варианты в ответах Кена и Ричарда).
до тех пор, пока матч всегда основан на начале category
string, тогда это работает просто отлично:
dt[substring(category, 1, nchar(industry)) == industry]
# category industry
# 1: administration admin
# 2: trucking truck
# 3: administration admin
# 4: trucking truck
# 5: nurse practitioner nurse
вы могли бы использовать stringi::stri_detect_fixed()
. Он векторизован над обоими str
и pattern
.
DT[stringi::stri_detect_fixed(category, industry)]
# category industry
# 1: administration admin
# 2: trucking truck
# 3: administration admin
# 4: trucking truck
# 5: nurse practitioner nurse
кроме того, stringr::str_detect()
можно использовать. Он также векторизуется над обоими его аргументами.
library(stringr)
DT[str_detect(category, fixed(industry))]
или базовая опция R-запустить grepl()
через mapply()
DT[mapply(grepl, industry, category, fixed = TRUE)]
или вы можете получить тот же результат с Vectorize(grepl)
.
DT[Vectorize(grepl)(industry, category, fixed = TRUE)]
все они дают один и тот же результат.
данные:
DT <- structure(list(category = c("administration", "nurse practitioner",
"trucking", "administration", "warehousing", "warehousing", "trucking",
"nurse practitioner", "nurse practitioner"), industry = c("admin",
"truck", "truck", "admin", "nurse", "admin", "truck", "nurse",
"truck")), .Names = c("category", "industry"), class = "data.frame", row.names = c(NA,
-9L))
setDT(DT)