考虑样本数据集:
dt <- data.table(data.frame(V1 = c("C1/R3","M2/R4")))
> dt
V1
1: C1/R3
2: M2/R4
对于dt
的每一行,我要提取级联字符C,M或R。例如,
dt[,V2 := stri_join_list(str_match_all(V1,"[CMR],sep="",collapse=""),by=seq_len(nrow(dt))]
> dt
V1 V2
1: C1/R3 CR
2: M2/R4 MR
但是,我有4200万行,上面的代码效率还不够。有没有一种方法可以不使用按行操作?当我跳过by参数时,每行都会得到CRMR
条目。
答案 0 :(得分:1)
一个选项使用sub
:
dt <- data.table(data.frame(V1 = c("C1/R3","M2/R4")))
dt$V2 <- sub("^([A-Z]+)[0-9]+/([A-Z]+)[0-9]+", "\\1\\2", dt$V1)
dt
V1 V2
1 C1/R3 CR
2 M2/R4 MR
答案 1 :(得分:0)
如您所述,如果您仅 希望将字母C,M和R捕获到data.table
中的新列中,那么以下操作应该可以有效地工作: :
dt[, V2 := gsub('[^CMR]', '', V1, perl=TRUE, useBytes=TRUE)]
模式[^CMR]
与不是 C M或R的任何字符匹配,然后我们替换为空字符串''
。
根据?gsub
的帮助:“如果可以使用useBytes = TRUE,则在匹配之前将不检查字符串,并且实际匹配会更快。”
最后,根据我的阅读,我相信使用perl=TRUE
比忽略它要快。但是,也许您可以同时测试这两种方法并使用真实数据对结果进行答复以为我们确认?