Hello stackoverflowers,
我想知道是否可以在同一数据表的两列之间的数据表中逐行使用%like%运算符。
以下可重复的示例将使其更加清晰。
首先准备数据
library(data.table)
iris <- as.data.table(iris)
iris <- iris[seq.int(from = 1, to = 150,length.out = 5)]
iris[, Species2 := c('set', "set|vers", "setosa", "nothing" , "virginica")]
因此数据集如下所示。
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Species2
1: 5.1 3.5 1.4 0.2 setosa set
2: 4.9 3.6 1.4 0.1 setosa set|vers
3: 6.4 2.9 4.3 1.3 versicolor setosa
4: 6.4 2.7 5.3 1.9 virginica nothing
5: 5.9 3.0 5.1 1.8 virginica virginica
我想按行使用以下命令。
iris[Species%like%Species2]
但它不明白我想要它排。那可能吗? 结果应该是1,2,5行。
答案 0 :(得分:2)
一种方法是逐行分组:
doAnswer(i -> {
((Runnable) i.getArguments()[0]).run();
return null;
}).when(executor).execute(any());
或者根据@docendodiscimus的评论,如果有重复的条目,你可以这样做:
iris[, .SD[Species %like% Species2], by = 1:5]
# : Sepal.Length Sepal.Width Petal.Length Petal.Width Species Species2
#1: 1 5.1 3.5 1.4 0.2 setosa set
#2: 2 4.9 3.6 1.4 0.1 setosa set|vers
#3: 5 5.9 3.0 5.1 1.8 virginica virginica
答案 1 :(得分:2)
您无法将矢量传递给pattern
的{{1}}参数,因为它会调用%like%
并且这些参数不会被矢量化。您可以使用grepl/grep
为每行调用mapply
来获得您想要的内容:
%like%
Microbenchmark主要是出于我自己的好奇心,但感兴趣的是其他任何人:
iris[mapply(function(x,y) x %like% y, Species, Species2) ]
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species Species2
#1: 5.1 3.5 1.4 0.2 setosa set
#2: 4.9 3.6 1.4 0.1 setosa set|vers
#3: 5.9 3.0 5.1 1.8 virginica virginica
由于set.seed(1)
dt <- data.table(Species = replicate(100000, paste0(sample(LETTERS, 6), collapse = "")),
Species2 = replicate(100000, paste0(sample(LETTERS, 3), collapse = "")))
microbenchmark::microbenchmark( mapply = dt[mapply(function(x,y) x %like% y, Species, Species2) ],
by_group1 = dt[, .SD[Species[1L] %like% Species2[1L]], by = .(Species, Species2)],
by_group2 = dt[, .SD[Species %like% Species2], by = 1:nrow(dt)],
str_detect = dt[stri_detect_regex(Species, Species2)],
by_species2 = dt[,.SD[Species %like% Species2], by = Species2],
by_species2I = dt[dt[, .I[Species %like% Species2], by = Species2]$V1],
times = 5)
Unit: milliseconds
expr min lq mean median uq max neval
mapply 669.9691 680.2241 700.3758 685.8262 715.8373 750.0224 5
by_group1 10906.2179 10908.0985 10951.5651 10914.7002 11009.0683 11019.7408 5
by_group2 16738.4390 16826.4793 16907.8428 16902.9490 16970.6143 17100.7324 5
str_detect 430.7768 431.1002 432.2279 431.9284 433.3488 433.9855 5
by_species2 2482.7583 2518.6858 2547.5882 2531.4913 2599.0159 2605.9899 5
by_species2I 110.1486 114.6775 115.9223 117.5270 118.5033 118.7553 5
操作非常慢,因此只运行了5次。使用by_group*
的@ eddi方法看起来最快(假设我的方法正确无误)。
另外,使用较少的组重新运行基准测试,在这种情况下似乎.I
仍然是最快的,而另一个by_species2I
仍然是最慢的(从#开始有意义) by_group*
的群组总是数据大小,而by_group2
的群组将接近数据大小。
by_group1
答案 2 :(得分:2)
${DC_CURRENCY_SELECTOR_VERIFY} = Encode String To Bytes ${DC_CURRENCY_SELECTOR_VERIFY} ASCII errors=ignore
只是%like%
的包装,因此模式(右侧)只能是长度1.您应该看到有关此的警告。
grepl
包允许您对stringi
参数进行矢量化。
pattern
如果你喜欢操作员风格而不是功能,你可以自己制作:
library(stringi)
iris[stri_detect_regex(Species, Species2)]
答案 3 :(得分:2)
各种答案都有正确的点点滴滴 - 按Species2
:
iris[, .SD[Species %like% Species2], by = Species2]
如果这很慢 - use .I instead。