gpt4 book ai didi

r 数据表 : Subsetting and assignment by reference in a for loop

转载 作者:行者123 更新时间:2023-12-04 14:29:22 25 4
gpt4 key购买 nike

看起来很简单,但是......好吧......

给定一个命名的正则表达式向量和一个数据表如下:

library(data.table)
regexes <- c(a="^A$")
dt <- fread("
a,A,1
a,B,1
b,A,1
")

输入数据表为

dt
# V1 V2 V3
# 1: a A 1
# 2: a B 1
# 3: b A 1

我对 regexes 中第一个元素的目标是:

如果 V1=="a" 设置 V3:=2。 EXCEPT 当 V2 匹配相应的正则表达式 ^A$ 时,则 V3:=3

(anames(regexes)[1]^A$regexes[1] , 23 只是为了演示目的。我还得到了更多的名称和正则表达式来循环,数据集大约有 300.000 行。)

所以预期的输出

#    V1 V2 V3
# 1: a A 3 (*)
# 2: a B 2 (**)
# 3: b A 1

(*) 3 因为 V1aV2 (A ) 匹配正则表达式,
(**) 2 因为 V1aV2 (B) 是不匹配 ^A$

我尝试循环遍历正则表达式并像这样通过管道传递子集:

for (x in seq(regexes)) 
dt[V1==names(regexes)[x], V3:=2][grepl(regexes[x], V2), V3:=3]

但是……

dt
# V1 V2 V3
# 1: a A 3
# 2: a B 2
# 3: b A 3 <- wrong, should remain 2

...它没有按预期工作,grepl 使用完整的 V2 列,而不仅仅是 V1=="a"子集。我还尝试了一些其他的方法,这些方法有效,但花费的时间太长(即不是使用 data.table 的方法)。

问题:去这里的最佳数据表方式是什么?我正在使用 packageVersion("data.table") ‘1.9.7’


请注意,我可以走数据框路线,例如像这样

df <- as.data.frame(dt)
for (x in seq(regexes)) {
idx <- df$V1==names(regexes)[x]
df$V3[idx] <- 2
df$V3[idx][grepl(regexes[x], df$V2[idx])] <- 3 # or ifelse()
}

但是 - 当然 - 如果可能的话,我不想将 data.table 转换为 data.frame 然后再转换回 data.table。

提前致谢!

最佳答案

... it does not work as expected, grepl uses the complete V2 column, not just the V1=="a" subset.

我会使用 stringi,它允许对正则表达式测试进行简单的矢量化:

library(stringi)
dt[V1 %in% names(regexes),
V3 := V3 + 1L + stri_detect(V2, regex = regexes[V1])
]

V1 V2 V3
1: a A 3
2: a B 2
3: b A 1

stri_detect 系列函数类似于来自 base 的 grepl

关于r 数据表 : Subsetting and assignment by reference in a for loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38084895/

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