gpt4 book ai didi

r - 如何将不同的 gsub 模式(变量函数)应用于 R 中的每一行 data.table

转载 作者:行者123 更新时间:2023-12-04 11:01:35 24 4
gpt4 key购买 nike

我有一个 data.table DT,其中包含一个字符串列和一个数字列,指示应从字符串开头提取多少个单词。

    > require(data.table)
> DT <- data.table(string_col = c("A BB CCC", "DD EEE FFFF GDG", "AB DFD EFGD ABC DBC", "ABC DEF")
, first_n_words = c(2, 3, 3, 1))
> DT
string_col first_n_words
1: A BB CCC 2
2: DD EEE FFFF GDG 3
3: AB DFD EFGD ABC DBC 3
4: ABC DEF 1

我想用 string_col 的前 n 个词添加一个新列,如下所示:

> output_DT
string_col first_n_words output_string_col
1: A BB CCC 2 A BB
2: DD EEE FFFF GDG 3 DD EEE FFFF
3: AB DFD EFGD ABC DBC 3 AB DFD EFGD
4: ABC DEF 1 ABC

这是可以使用的 gsub 语法:

> gsub(paste0("^((\\w+\\W+){", first_n_words - 1, "}\\w+).*$"),"\\1", string_col)

我基本上需要为每一行创建这个 gsub 函数,在将它应用于该行的 string_col 之前使用该行的 first_n_words。我只对 data.table 语法解决方案感兴趣,因为它是一个非常大的数据集。最需要 gsub 解决方案。


编辑:我已经尝试了以下但它不起作用

> DT[, output_string_col := gsub(paste0("^((\\w+\\W+){", first_n_words - 1, "}\\w+).*$"),"\\1", string_col)]
Warning message:
In gsub(paste0("^((\\w+\\W+){", first_n_words - 1, "}\\w+).*$"), :
argument 'pattern' has length > 1 and only the first element will be used
>## This is not the desired output
> DT
string_col first_n_words output_string_col
1: A BB CCC 2 A BB
2: DD EEE FFFF GDG 3 DD EEE
3: AB DFD EFGD ABC DBC 3 AB DFD
4: ABC DEF 1 ABC DEF

这不是想要的输出

最佳答案

继续使用 data.table 的答案是使用分组操作,因为您需要 gsub 中的值,而不是向量:

DT[,line := .I]
DT[, output_string_col := gsub(paste0("^((\\w+\\W+){", first_n_words - 1, "}\\w+).*$"),"\\1", string_col),by = line]

> DT
string_col first_n_words line output_string_col
1: A BB CCC 2 1 A BB
2: DD EEE FFFF GDG 3 2 DD EEE FFFF
3: AB DFD EFGD ABC DBC 3 3 AB DFD EFGD
4: ABC DEF 1 4 ABC

编辑

正如@Franck 所说,分组应该放在first_n_words上以提高效率

DT[, output_string_col := gsub(paste0("^((\\w+\\W+){", first_n_words[1] - 1, "}\\w+).*$"),"\\1", string_col),by = first_n_words]

这个修改版本的基准测试给出了更快的结果:

library(microbenchmark)

denis <- function(x){
x[, output_string_col := gsub(paste0("^((\\w+\\W+){", first_n_words[1] - 1, "}\\w+).*$"),"\\1", string_col),by = first_n_words]
}



Tim <- function(x){
x[, output_string_col := apply(x, 1, function(x) {
gsub(paste0("^((\\w+\\W+){", as.numeric(x[2]) - 1, "}\\w+).*$"), "\\1", x[1])
})]
}

miss <- function(x){
x[, output_string_col := stringr::word(string_col, end = first_n_words)]
}

DT <- DT[sample(1:4, 1000, replace = TRUE),]

microbenchmark(
Tim(DT),
miss(DT),
denis(DT)
)

Unit: milliseconds
expr min lq mean median uq
Tim(DT) 56.851716 57.836126 60.435164 58.714486 60.753051
miss(DT) 11.042056 11.516928 12.427029 11.871800 12.617031
denis(DT) 1.993437 2.355283 2.555936 2.615181 2.680001
max neval
111.169277 100
20.916932 100
3.530668 100

关于r - 如何将不同的 gsub 模式(变量函数)应用于 R 中的每一行 data.table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52363435/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com