Подсчет строки, за которой следуют отдельные строки в r - PullRequest
2 голосов
/ 25 мая 2020

Я пытаюсь подсчитать количество вхождений строки, за которой следует другая строка в r. Кажется, я не могу заставить регулярное выражение рассчитать это правильно.

В качестве примера:

v <- c("F", "F", "C", "F", "F", "C", "F", "F")
b <- str_count(v, "F(?=C)")

Я хотел бы, чтобы b сказал мне, сколько раз за строкой F следовала строка C в векторе v (который должен быть равен 2).

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

Кроме того, я обнаружил, что в регулярном выражении (? = ...) должно быть указано «за которым следует», однако этого, похоже, недостаточно.

Ответы [ 2 ]

2 голосов
/ 25 мая 2020

У вас нет одной строки. У вас есть отдельные струны. Вы можете проверить, следует ли за F C, сдвигая, используя [ для подмножества.

sum(v[-length(v)] == "F" & v[-1] == "C")
#sum(v == "F" & c(v[-1] == "C", FALSE)) #Alternative
#[1] 2

Чтобы использовать stringr::str_count, вы можете paste v в одну строку.

stringr::str_count(paste(v, collapse = ""), "F(?=C)")
#[1] 2

А для рядов data.frame:

set.seed(42)
v <- as.data.frame(matrix(sample(c("F", "C"), 25, TRUE), 5))
stringr::str_count(apply(v, 1, paste, collapse = ""), "F(?=C)")
#[1] 1 1 2 1 1
1 голос
/ 25 мая 2020

Вы можете использовать lag() из dplyr:

library(dplyr)
sum(v == "C" & lag(v) == "F", na.rm = TRUE)

(na.rm = TRUE потому, что первое значение lag(v) - NA).


Ваш комментарий отмечает, что вы также заинтересованы в применении этого к каждой строке фрейма данных. Это можно сделать, повернув данные, чтобы они были длиннее, затем применив сгруппированное изменение, а затем снова повернув данные, чтобы они были шире. В примере набора данных:

example <- tibble(id = 1:3,
                  s1 = c("F", "F", "F"),
                  s2 = c("C", "F", "C"),
                  s3 = c("C", "C", "F"),
                  s4 = c("F", "C", "C"))

example %>%
  pivot_longer(s1:s4) %>%
  group_by(id) %>%
  mutate(fc_count = sum(value == "C" & lag(value) == "F", na.rm = TRUE)) %>%
  ungroup() %>%
  pivot_wider(names_from = name, values_from = value)

Результат:

# A tibble: 3 x 6
     id fc_count s1    s2    s3    s4   
  <int>    <int> <chr> <chr> <chr> <chr>
1     1        1 F     C     C     F    
2     2        1 F     F     C     C    
3     3        2 F     C     F     C    

Обратите внимание, что это предполагало, что данные имели что-то вроде столбца id, который однозначно идентифицирует каждую исходную строку. Если это не так, вы можете сначала добавить его с mutate(id = row_number()).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...