数据帧每一行的字符串部分匹配

时间:2019-08-06 14:51:45

标签: r

以虹膜数据为例来说明我的问题,我想对“ .5”进行部分匹配并获取位置的索引(在我的实际数据中,0.5实际上是字符串“ _mutations”)。

我打算遍历每一行,执行部分匹配,获取第一个匹配的索引。我已经使用了以下内容;

idx = regexpr(pattern, txt[i,], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)[1]

idx = regexec(pattern, txt[i,], ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)[1]

gregexpr(pattern, txt[j,], ignore.case = FALSE, perl = FALSE,
          fixed = FALSE, useBytes = FALSE)

stri_locate_first_regex(txt[i,], pattern)

str_detect(txt[i,], pattern)

示例数据如下:

library(ggplot2)
txt = iris
pattern=".5"

预期结果是第一个匹配项的索引。

4 个答案:

答案 0 :(得分:2)

将所有值替换为TRUE

df <- iris
# [] notation preserves structure
df[] <- lapply(X = df, function(x) {
    grepl(pattern = ".5",
          x = as.character(x),
          fixed = TRUE)
})

获取每列TRUE值的位置

sapply(X = df, which)

结果

# $Sepal.Length
# [1]  34  37  42  54  55  81  82  90  91 105 111 117 148
# 
# $Sepal.Width
# [1]   1  18  28  37  41  44  70  73  90  99 107 109 114 147
# 
# $Petal.Length
# [1]   4   8  10  11  16  20  22  28  32  33  35  40  49  52  56  61  67  69  79  80
# [21]  85  86 107 113 117 138
# 
# $Petal.Width
# [1]  24  52  53  55  62  67  69  73  79  85  87 101 110 120 134 145
# 
# $Species
# integer(0)

注释

有很多方法可以解决此问题。我喜欢这种解决方案,因为结果可读性很强,但我认为很大程度上取决于口味。

答案 1 :(得分:1)

您是否尝试过将whichgrepl结合使用?

which(grepl("0.5", iris$Petal.Width))[1]

编辑

在您发表评论之后,这是另一种尝试,它为所有行索引的向量提供了部分匹配。

library(tidyverse)

iris %>%
  mutate(row_index = as.numeric(rownames(.))) %>%
  filter_all(any_vars(grepl("0.5", .))) %>%
  pull()

虽然不确定这是最简单的方法。

答案 2 :(得分:0)

以下内容会产生所需的输出吗?

grep(pattern, txt[i,])[1]

答案 3 :(得分:0)

您可以使用rapply使用grepl在每个单元格中搜索模式,并将单元格值替换为TRUEFALSE。然后使用rowSums逐行累加所有TRUE(1)和FALSE(0)单元,并查看是否至少有一个匹配项>= 1

rowSums(rapply(iris, function(x) grepl(pattern = ".5", x, fixed = T), how = "replace")) >= 1

在这里,我假设您希望.匹配一个句点而不是任何字符(如果不转义,则它将与正则表达式匹配(即\\.),或fixed = TRUE。另外,请注意,如果要在更大的数据集上搜索"_mutations",则fixed = TRUE会更快:

然后,将其用作子集:

idx <- rowSums(rapply(iris, function(x) grepl(pattern = ".5", x, fixed = T), how = "replace")) >= 1
head(iris[idx, ])

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
8           5.0         3.4          1.5         0.2  setosa
10          4.9         3.1          1.5         0.1  setosa
11          5.4         3.7          1.5         0.2  setosa
16          5.7         4.4          1.5         0.4  setosa