从 tibble 中删除子字符串行
Remove substring rows from tibble
我有一个问题:
df <- tibble(x = c('a', 'ab', 'abc', 'abcd', 'abd', 'efg'))
我想删除作为其他行的子字符串的行,导致:
result <- tibble(x = c('abcd', 'abd', 'efg'))
该解决方案必须非常有效,因为有约 100 万行文本。
str_extract(df$x, "foo") == "foo"
是为了测试“foo”是否是df$x
中任意元素的子串。它始终至少为 1,因为 x 始终是其自身的子串。如果这个数字更高,它也是另一个元素的子串,所以我们需要使用 filter(!)
.
删除它们
library(tidyverse)
df <- tibble(x = c('a', 'ab', 'abc', 'abcd', 'abd', 'efg'))
df %>% filter(! (x %>% map_lgl(~ sum(str_extract(df$x, .x) == .x, na.rm = TRUE) > 1)))
#> # A tibble: 3 x 1
#> x
#> <chr>
#> 1 abcd
#> 2 abd
#> 3 efg
由 reprex package (v2.0.0)
于 2022-02-18 创建
在小数据集上速度较慢(在那些情况下速度不是问题)但在更大的数据集上速度更快。速度取决于与数据大小相比有多少唯一组。
df <- arrange(df, desc(nchar(x)))
my_strings <- df$x
i <- 1
while(i < length(my_strings)){
indices <- which(str_detect(my_strings[[i]], my_strings[(i+1):length(my_strings)])) + i
if(length(indices) > 0) my_strings <- my_strings[-indices]
i <- i + 1
}
可能的改进但未测试:
setDT(df)
indices_df <- df[, .(indices = list(.I)), by = x][order(-nchar(x))]
my_strings <- indices_df$x
i <- 1
while(i < length(my_strings)){
indices <- which(str_detect(my_strings[[i]], my_strings[(i+1):length(my_strings)])) + i
if(length(indices) > 0) my_strings <- my_strings[-indices]
i <- i + 1
}
df[indices_df[x %in% my_strings, unlist(indices)]]
我有一个问题:
df <- tibble(x = c('a', 'ab', 'abc', 'abcd', 'abd', 'efg'))
我想删除作为其他行的子字符串的行,导致:
result <- tibble(x = c('abcd', 'abd', 'efg'))
该解决方案必须非常有效,因为有约 100 万行文本。
str_extract(df$x, "foo") == "foo"
是为了测试“foo”是否是df$x
中任意元素的子串。它始终至少为 1,因为 x 始终是其自身的子串。如果这个数字更高,它也是另一个元素的子串,所以我们需要使用 filter(!)
.
library(tidyverse)
df <- tibble(x = c('a', 'ab', 'abc', 'abcd', 'abd', 'efg'))
df %>% filter(! (x %>% map_lgl(~ sum(str_extract(df$x, .x) == .x, na.rm = TRUE) > 1)))
#> # A tibble: 3 x 1
#> x
#> <chr>
#> 1 abcd
#> 2 abd
#> 3 efg
由 reprex package (v2.0.0)
于 2022-02-18 创建在小数据集上速度较慢(在那些情况下速度不是问题)但在更大的数据集上速度更快。速度取决于与数据大小相比有多少唯一组。
df <- arrange(df, desc(nchar(x)))
my_strings <- df$x
i <- 1
while(i < length(my_strings)){
indices <- which(str_detect(my_strings[[i]], my_strings[(i+1):length(my_strings)])) + i
if(length(indices) > 0) my_strings <- my_strings[-indices]
i <- i + 1
}
可能的改进但未测试:
setDT(df)
indices_df <- df[, .(indices = list(.I)), by = x][order(-nchar(x))]
my_strings <- indices_df$x
i <- 1
while(i < length(my_strings)){
indices <- which(str_detect(my_strings[[i]], my_strings[(i+1):length(my_strings)])) + i
if(length(indices) > 0) my_strings <- my_strings[-indices]
i <- i + 1
}
df[indices_df[x %in% my_strings, unlist(indices)]]