使用 grepl 在管道中创建 data.table 列
create data.table column in pipe with grepl
我正在寻找一种在管道序列中创建新的 data.table
列的方法,使用 grepl
查找特定字符串的任何出现。
我已经 and 寻求帮助,围绕这个主题似乎有很多问题,但似乎并没有直接解决我的问题。
此外,我可能误解了 data.table
语法并引用了 Reference semantics vignettes。我有下面的代码,其中有两种方法可能是 piped/chained 但似乎不起作用。明确创建 data.table
列的最后一个选项似乎有效,但我想知道它是否可以 chained/piped.
据我了解,在 data.table
中使用 lapply
会将函数应用于整个列(即 sum
、mean
、na.approx
我从另一个发布的问题中发现)但不会按行工作。此外,我可以使用 new_col := function(x)
将函数应用于给定列中的每一行。所以我会认为其中一个可以工作。
我(只是有点)知道 grepl
需要一个单一的值,但提供了一个向量,我不确定如何解决这个问题。
感谢任何帮助,谢谢。
> library(data.table)
>
> a = c("housefly",
+ "house fly",
+ "HOUSEFLY",
+ "HOUSE FLY")
>
> dt = data.table(insect = c("housefly",
+ "house fly",
+ "HOUSEFLY",
+ "HOUSE FLY",
+ "dragonfly",
+ "dragon fly"))
>
> # does not work but I could put this in chain/pipe
> dt[, fly_check := sapply(.SD, grepl, paste(a, collapse = "|")), .SDcols = "insect"]
Warning message:
In FUN(X[[i]], ...) :
argument 'pattern' has length > 1 and only the first element will be used
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly TRUE
6: dragon fly TRUE
>
> # does not work but I could put this in chain/pipe
> dt[, fly_check := ifelse(grepl(insect, paste(a, collapse = "|")), TRUE, FALSE)]
Warning message:
In grepl(insect, paste(a, collapse = "|")) :
argument 'pattern' has length > 1 and only the first element will be used
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly TRUE
6: dragon fly TRUE
>
> # works but can't be chained/piped
> dt$fly_check = sapply(dt$insect, grepl, pattern = paste(a, collapse = "|"))
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly FALSE
6: dragon fly FALSE
看起来你正在寻找这个,尽管@chinsoon12(在评论中)给出了一个更简单的解决方案,它只是直接传递列名:
逻辑:在 data.table 中,如果您使用 .SD 参数调用它,则表示数据的子集,这也表明该列不是作为向量而是作为 data.table 对象传递的(因此您必须使用 Vectorize 或其他操作),另一方面,如果你直接将它作为列传递,grepl 在处理类似向量的结构时没有问题(@Chinsoon12 解决方案)。
您可以查看 this,它很有启发性 link。
dt[, fly_check := (Vectorize(grepl)(paste0(a, collapse = "|"),.SD)), .SDcols = c("insect")]
这导致:
# insect fly_check
#1: housefly TRUE
#2: house fly TRUE
#3: HOUSEFLY TRUE
#4: HOUSE FLY TRUE
#5: dragonfly FALSE
#6: dragon fly FALSE
我认为这只是 %in%
对 a
值的简单应用
dt[ , fly_check := insect %in% a]
这似乎比将 grepl
应用于折叠的 a
值作为模式更简单。
dt[ , fly_check := grepl( paste0(a, collapse="|") , insect)]
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly FALSE
6: dragon fly FALSE
我想如果您通过 ignore.case=TRUE
获得了通用性或需要 'perl' 或 'fixed' 参数提供的便利,我想您可能仍会选择 grepl
策略。
我正在寻找一种在管道序列中创建新的 data.table
列的方法,使用 grepl
查找特定字符串的任何出现。
我已经
此外,我可能误解了 data.table
语法并引用了 Reference semantics vignettes。我有下面的代码,其中有两种方法可能是 piped/chained 但似乎不起作用。明确创建 data.table
列的最后一个选项似乎有效,但我想知道它是否可以 chained/piped.
据我了解,在 data.table
中使用 lapply
会将函数应用于整个列(即 sum
、mean
、na.approx
我从另一个发布的问题中发现)但不会按行工作。此外,我可以使用 new_col := function(x)
将函数应用于给定列中的每一行。所以我会认为其中一个可以工作。
我(只是有点)知道 grepl
需要一个单一的值,但提供了一个向量,我不确定如何解决这个问题。
感谢任何帮助,谢谢。
> library(data.table)
>
> a = c("housefly",
+ "house fly",
+ "HOUSEFLY",
+ "HOUSE FLY")
>
> dt = data.table(insect = c("housefly",
+ "house fly",
+ "HOUSEFLY",
+ "HOUSE FLY",
+ "dragonfly",
+ "dragon fly"))
>
> # does not work but I could put this in chain/pipe
> dt[, fly_check := sapply(.SD, grepl, paste(a, collapse = "|")), .SDcols = "insect"]
Warning message:
In FUN(X[[i]], ...) :
argument 'pattern' has length > 1 and only the first element will be used
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly TRUE
6: dragon fly TRUE
>
> # does not work but I could put this in chain/pipe
> dt[, fly_check := ifelse(grepl(insect, paste(a, collapse = "|")), TRUE, FALSE)]
Warning message:
In grepl(insect, paste(a, collapse = "|")) :
argument 'pattern' has length > 1 and only the first element will be used
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly TRUE
6: dragon fly TRUE
>
> # works but can't be chained/piped
> dt$fly_check = sapply(dt$insect, grepl, pattern = paste(a, collapse = "|"))
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly FALSE
6: dragon fly FALSE
看起来你正在寻找这个,尽管@chinsoon12(在评论中)给出了一个更简单的解决方案,它只是直接传递列名:
逻辑:在 data.table 中,如果您使用 .SD 参数调用它,则表示数据的子集,这也表明该列不是作为向量而是作为 data.table 对象传递的(因此您必须使用 Vectorize 或其他操作),另一方面,如果你直接将它作为列传递,grepl 在处理类似向量的结构时没有问题(@Chinsoon12 解决方案)。
您可以查看 this,它很有启发性 link。
dt[, fly_check := (Vectorize(grepl)(paste0(a, collapse = "|"),.SD)), .SDcols = c("insect")]
这导致:
# insect fly_check
#1: housefly TRUE
#2: house fly TRUE
#3: HOUSEFLY TRUE
#4: HOUSE FLY TRUE
#5: dragonfly FALSE
#6: dragon fly FALSE
我认为这只是 %in%
对 a
值的简单应用
dt[ , fly_check := insect %in% a]
这似乎比将 grepl
应用于折叠的 a
值作为模式更简单。
dt[ , fly_check := grepl( paste0(a, collapse="|") , insect)]
> dt
insect fly_check
1: housefly TRUE
2: house fly TRUE
3: HOUSEFLY TRUE
4: HOUSE FLY TRUE
5: dragonfly FALSE
6: dragon fly FALSE
我想如果您通过 ignore.case=TRUE
获得了通用性或需要 'perl' 或 'fixed' 参数提供的便利,我想您可能仍会选择 grepl
策略。