Частичное точное совпадение строк

#r #data-manipulation #grepl

#r #манипулирование данными #grepl

Вопрос:

Я много искал, но не смог найти решение… Я думаю, что для многих из вас это легко… но не для меня.

  df <- data.frame(site = c("11", " 4 , 111", "3,1 ", "4,11111 "))
> df
      site
1       11
2  4 , 111
3     3,1 
4 4,11111
  

У меня есть столбец, в котором коды нескольких сайтов могут быть разделены запятой (а не случайными пробелами, которые могут возникнуть). Я пытаюсь найти строки, соответствующие строковым номерам сайтов, представляющим интерес.

Таким образом, результаты поиска строк, в которых сайт имеет либо 11, либо 3 совпадения ‘c (1,3)’, должны возвращать:

 [1] 1 0 1 0
  

Кажется, я не могу это понять… Я думаю, ответ будет включать

 temp <- strsplit(df$site, ",")
  

, но, похоже, я не могу понять, как применять функции к спискам после этого шага… Я бы сделал

 grepl(c("^11$", "^3$"), temp)
  

но это не работает.

Комментарии:

1. Что представляют единицы и 0? Являются ли они просто «да» и «нет» или они должны указывать количество совпадений в каждой строке?

2. Несколько неторопливая версия: library(tidyverse) ; df %>% group_by(row = row_number()) %>% separate_rows(site, sep = ',', convert = TRUE) %>% summarise(result = as.integer(any(site == 11 | site == 3)))

Ответ №1:

Поскольку вы ищете точное совпадение, а не соответствие шаблону, вы можете попробовать это:

 df <- data.frame(site = c("11", " 4 , 111", "3,1 ", "4,11111 "), stringsAsFactors = FALSE)
as.integer(unlist(lapply(strsplit(df$site, split=","), function(x) any(x == 3 | x == 11))))

[1] 1 0 1 0
  

Комментарии:

1. Вы могли бы также немного сжать код sapply(strsplit(df$site, split=","), function(x) any(x %in% c(3,11)))

2. Эти изменения заставили его работать полностью: sapply(strsplit(как.character(df $site), split=»,»), функция (x) любая(как.numeric(x) %в% c(11,1))). Большое спасибо!

Ответ №2:

Вы можете попробовать использовать sapply

 as.integer(sapply(df$site,function(x)grepl("^11|^3",x)))

[1] 1 0 1 0
  

Комментарии:

1. Поиск ‘1’ приводит только к 1 0 0 0, что неверно.

Ответ №3:

Мы можем просто сделать grep

  (grepl("\b(3|11)\b", df$site))
#[1] 1 0 1 0