使用 grep 对 data.table 中的行进行子集化,比较行内容
Using grep to subset rows from a data.table, comparing row content
DT <- data.table(num=c("20031111","1112003","23423","2222004"),y=c("2003","2003","2003","2004"))
> DT
num y
1: 20031111 2003
2: 1112003 2003
3: 23423 2003
4: 2222004 2004
我想比较两个单元格的内容,并根据布尔值执行操作。例如,如果 "num" 匹配年份,则创建一个包含该值的列 x。我考虑过基于 grep 的子集化,这很有效,但每次都会自然地检查 whole 列,这似乎很浪费
DT[grep(y,num)] # works with a pattern>1 warning
我可以按我的方式申请(),但也许有 data.table 方式?
谢谢
你可以这样做
DT[, x := grep(y, num, value = TRUE, fixed = TRUE), by = .(num, y)]
#> DT
# num y x
#1: 20031111 2003 20031111
#2: 1112003 2003 1112003
#3: 23423 2003 NA
#4: 2222004 2004 2222004
如果您喜欢使用 stringi
包,这是一种利用 stringi
函数向量化模式和字符串这一事实的方法:
DT[stri_detect_fixed(num, y), x := num])
根据数据,它可能比 Veerenda Gadekar 发布的方法更快。
DT <- data.table(num=paste0(sample(1000), sample(2001:2010, 1000, TRUE)),
y=as.character(sample(2001:2010, 1000, TRUE)))
microbenchmark(
vg = DT[, x := grep(y, num, value=TRUE, fixed=TRUE), by = .(num, y)],
nk = DT[stri_detect_fixed(num, y), x := num]
)
#Unit: microseconds
# expr min lq mean median uq max neval
# vg 6027.674 6176.397 6513.860 6278.689 6370.789 9590.398 100
# nk 975.260 1007.591 1116.594 1047.334 1110.734 3833.051 100
DT <- data.table(num=c("20031111","1112003","23423","2222004"),y=c("2003","2003","2003","2004"))
> DT
num y
1: 20031111 2003
2: 1112003 2003
3: 23423 2003
4: 2222004 2004
我想比较两个单元格的内容,并根据布尔值执行操作。例如,如果 "num" 匹配年份,则创建一个包含该值的列 x。我考虑过基于 grep 的子集化,这很有效,但每次都会自然地检查 whole 列,这似乎很浪费
DT[grep(y,num)] # works with a pattern>1 warning
我可以按我的方式申请(),但也许有 data.table 方式?
谢谢
你可以这样做
DT[, x := grep(y, num, value = TRUE, fixed = TRUE), by = .(num, y)]
#> DT
# num y x
#1: 20031111 2003 20031111
#2: 1112003 2003 1112003
#3: 23423 2003 NA
#4: 2222004 2004 2222004
如果您喜欢使用 stringi
包,这是一种利用 stringi
函数向量化模式和字符串这一事实的方法:
DT[stri_detect_fixed(num, y), x := num])
根据数据,它可能比 Veerenda Gadekar 发布的方法更快。
DT <- data.table(num=paste0(sample(1000), sample(2001:2010, 1000, TRUE)),
y=as.character(sample(2001:2010, 1000, TRUE)))
microbenchmark(
vg = DT[, x := grep(y, num, value=TRUE, fixed=TRUE), by = .(num, y)],
nk = DT[stri_detect_fixed(num, y), x := num]
)
#Unit: microseconds
# expr min lq mean median uq max neval
# vg 6027.674 6176.397 6513.860 6278.689 6370.789 9590.398 100
# nk 975.260 1007.591 1116.594 1047.334 1110.734 3833.051 100