data.table对象D中自定义提取尾词函数无法运行的技术求助
嘿,我来帮你搞定这个问题!首先,你的getLasTerm函数应该是针对单个字符串写的,但data.table是按向量批量操作的,直接传整列的话就会出问题——毕竟函数默认只处理单个值,没法自动遍历整个向量。下面给你两种思路,一种是改造你的函数适配向量,另一种是用更高效的原生矢量化操作(更推荐后者,因为data.table对矢量化操作的速度支持更好)。
首先,明确假设
我假设你的data.table里存待处理文本的列名叫input_text,所有文本都是用下划线_分隔的,比如"in_the_years"这种格式。如果列名不一样,你只要替换成自己的列名就行。
方法一:改造你的getLasTerm函数为矢量化版本
如果你想继续用自己写的函数,只需要用Vectorize()把它包装成支持向量输入的版本:
# 你的原函数 getLasTerm <- function(x, sep) { parts <- strsplit(x, sep)[[1]] parts[length(parts)] } # 转成矢量化函数 getLasTerm_vec <- Vectorize(getLasTerm) # 在data.table中使用 D[, predict := getLasTerm_vec(input_text, "_")]
这样函数就会自动遍历input_text列的每一个元素,返回对应的最后一个词。
方法二:用更高效的原生矢量化操作(推荐)
data.table配合stringi或者基础包的函数,能更快处理这类字符串操作,不需要额外包装函数:
1. 新增predict列(提取最后一个词)
用stringi包的stri_last_split_fixed函数,它天生支持向量,而且速度很快:
library(stringi) D[, predict := stri_last_split_fixed(input_text, "_", n = 2)[, 2]]
解释一下:n=2表示把字符串分成前半部分和最后一个词两部分,取第二部分就是我们要的最后一个词。
如果你不想装额外包,用基础包的strsplit配合sapply也可以:
D[, predict := sapply(strsplit(input_text, "_"), tail, n = 1)]
这里sapply会遍历strsplit返回的每个列表元素,用tail取最后一个元素。
2. 新增queryWord列(提取前2个词并合并)
同样用stringi的方法,拆分后取前两个词再合并:
D[, queryWord := stri_join_list(lapply(stri_split_fixed(input_text, "_"), head, n = 2), sep = "_")]
或者用基础包的sapply:
D[, queryWord := sapply(strsplit(input_text, "_"), function(x) paste(head(x, 2), collapse = "_"))]
这个逻辑是:先拆分每个字符串为词的列表,取前两个,再用下划线把它们合并成一个字符串。
验证一下
假设你的D是这样的:
library(data.table) D <- data.table(input_text = c("in_the_years", "one_two_three_four", "a_b_c"))
运行上面的代码后,D会变成:
input_text queryWord predict 1 in_the_years in_the years 2 one_two_three_four one_two four 3 a_b_c a_b c
完全符合你的需求!
内容的提问来源于stack exchange,提问作者Kpakpo

