从数据框中提取与向量匹配的行,但匹配必须一直在字符串末尾的值中

时间:2018-02-03 19:56:23

标签: r regex dplyr

我有一个如下数据框:

sampleid <- c("patient_sdlkfjd_2354_CSF_CD19+", "control_sdlkfjd_2632_CSF_CD8+", "control_sdlkfjd_2632_CSF")
values = rnorm(3, 8, 3)

df <- data.frame(sampleid, values)

我还有一个类似以下的矢量:

matches <- c("632_CSF_CD8+", "632_CSF").

我想提取此数据框中的行,其中包含sampleid列中值末尾的匹配项。从这个例子中,你可以看到为什么字符串的结尾很重要,因为我有两个样本包含&#34; 632_CSF,&#34;但它们是不同的样本。如果我选择仅将匹配更改为:

matches <- c("632_CSF").

然后我只想输出数据帧的第三行,因为这是在sampleid末尾匹配的唯一一行。

如何实现这一目标?

谢谢!

3 个答案:

答案 0 :(得分:2)

在模式中使用$表示它出现在字符串的末尾。

grep("632_CSF$", sampleid, value=TRUE)
[1] "control_sdlkfjd_2632_CSF"

答案 1 :(得分:1)

您可以使用stringr和一些操作进行此操作。

你需要对正则表达式进行编码,它是用quotemeta函数完成的。

下一步是添加$以确保匹配位于字符串的末尾,然后将所有matches连接到一个带有正则表达式OR的地方 - |

然后它应该与str_detect一起使用以获得布尔索引。

library(stringr)

# taken from here
# https://stackoverflow.com/a/14838753/1030110
quotemeta <- function(string) {
  str_replace_all(string, "(\\W)", "\\\\\\1")
}

matches_with_end <- sapply(matches, function(x) { paste0(quotemeta(x), '$') })
joined_matches <- paste(matches_with_end, collapse = '|')

ind <- str_detect(df$sampleid, joined_matches)
# [1] FALSE  TRUE  TRUE

df[ind, ]
#                        sampleid    values
# 2 control_sdlkfjd_2632_CSF_CD8+ 10.712634
# 3      control_sdlkfjd_2632_CSF  7.001628

答案 2 :(得分:1)

建议使您的数据集更加规范。

library(tidyverse)

df_regular <- df %>%
  separate(
  sampleid,
  into = c("patient_type",
         "test_number",
         "patient_group",
         "patient_id"),
  extra = "merge") %>%
mutate(patient_id = str_pad(patient_id, 9, side = c("left"), pad = "0"))

df_regular

df_regular %>%
  filter(patient_group %in% "2632" & patient_id %in% "000000CSF")