#r
#r
Вопрос:
скажем, у меня есть:
test <- c("you", "he", "I", "you are", "you you")
grep("you", test, value = FALSE)
это дает мне [1] 1 4 5
что я могу сделать, чтобы учесть двойное вхождение ‘you’ в 5, возможно, получить результат: [1] 1 4 5 5 вместо этого?
Комментарии:
1. разве вектор, подобный
1 0 0 1 2
более полезному?rep(seq_along(test), stringr::str_count(test, 'you'))
2. @rawr это было просто предложение, просто 4 было бы наиболее полезным результатом в моем случае, я думаю, но я пока не совсем уверен. на самом деле точный формат вывода не имеет значения.
Ответ №1:
За исключением (3), все это только две строки кода, и, за исключением (1), все используют только базовую R. Все принимают общие регулярные выражения, за исключением (2) и (5), которые предполагают более строгое предположение о фиксированных строках — в примере вопроса используется фиксированная строка.
(1) кажется самым простым при поддержке регулярных выражений, но (4) лишь немного сложнее, хотя все еще поддерживает регулярные выражения и использует только базовый R.
1) strapplyc strapplyc
извлекает список всех you
вхождений, по одному вектору на компонент test
, а затем lengths
выдает длину каждого из этих векторов freq
. Наконец, используйте rep
, чтобы преобразовать это в желаемую форму. Это решение или (4) кажется самым простым из тех, которые мы представляем.
library(gsubfn)
freq <- lengths(strapplyc(test, "you")) # 1 0 0 1 2
rep(seq_along(freq), freq)
[1] 1 4 5 5
2) gregexpr 1 Это похоже на последнее, за исключением того, что оно использует gregexpr
вместо strapplyc
. Проблема gregexpr
заключается в его нерегулярном выводе, когда он сообщает об отсутствии вхождений как -1, поэтому мы добавляем «you» к каждому элементу ввода, а затем берем длины минус 1, чтобы не считать добавленные you
. Этот вариант лишь немного сложнее с дополнительным учетом того, что нечетный способ gregexpr
указывает на отсутствие совпадений; однако у него есть то преимущество, что он использует только базовое R, но для этого требуется, чтобы поисковый запрос был фиксированным, а не регулярным выражением.
freq <- lengths(gregexpr("you", paste(test, "you"))) - 1
rep(seq_along(freq), freq)
3) gregexpr 2 Это также использует gregexpr
, но использует другой подход к преобразованию его в желаемую форму. Преобразуйте g
выходные gregexpr
данные в data.frame с помощью stack
. stack
требуется, чтобы список ввода был назван, и мы также должны удалить вхождения -1, g
чтобы получить правильный ответ.. Результатом, сформированным с помощью stack
, является фрейм данных с двумя столбцами, в котором столбец factor ind
содержит решение. Наконец, преобразуйте ind
в целое число.
g <- gregexpr("you", test)
names(g) <- seq_along(g)
as.integer(as.character(stack(lapply(g, setdiff, -1L))$ind))
## [1] 1 4 5 5
4) gregexpr 3 Удаляет значения -1 в gregexpr
выходных данных, чтобы lengths
их можно было использовать. Он использует только базовый R, а также работает с регулярными выражениями.
g <- gregexpr("you", test)
rep(seq_along(g), lengths(lapply(g, setdiff, -1L)))
## [1] 1 4 5 5
5) подсчет.поля Другим базовым решением R является использование count.fields
, которое будет подсчитывать поля между вхождениями you
, поэтому мы вычитаем единицу, чтобы получить вхождения you
самого себя. Это может обрабатывать только фиксированные строки, тогда как другие решения могут обрабатывать регулярные выражения.
freq <- count.fields(textConnection(test), sep = "you") - 1
rep(seq_along(freq), freq)
## [1] 1 4 5 5
Комментарии:
1. круто, спасибо, это помогло бы, однако я бы не хотел просто копировать это, поскольку это определенно не в моей лиге. если я просто выполняю gregexpr («вы», тест), я получаю результат, с которым я не могу справиться, почему это? или вы можете кратко объяснить свой код?
2. большое вам спасибо! можно ли мне просто использовать подход gregexpr 2 для университетского задания? я упомяну, что у меня есть это из Интернета, хотя это действительно очень очевидно.
3. Я не против, если ваш инструктор согласится.
4. Добавили 4) gregexpr 3