Подсчитывать значения в data.frame, которые попадают в диапазон, используя скользящее окно

#r

#r

Вопрос:

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

Что я хочу в не-коде, так это:
— Количество вхождений «m4C» (столбец 1) в положительную цепочку (столбец 6) за первые 200 bp (столбец 2)
— Повторить вышеуказанное для следующих 200 bp или любого размера окна, который я хочу выбрать.
Я также внесу изменения, чтобы посмотреть на другие типы изменений и обе цепочки, как только у меня будет базовый фрагмент.

Я просмотрел rollapply из zoo, но не знаю, как создать функцию для этой комбинации условий. Я также видел это https://stats.stackexchange.com/questions/3051/mean-of-a-sliding-window-in-r
, но я не знаю достаточно, чтобы вывести его за рамки простой функции, используемой там. Я нашел способ сделать это в Excel с помощью COUNTIFS

 COUNTIFS($A:$A,"m4C",$F:$F," ",$B:$B,">"amp;$S3,$B:$B,"<"amp;$T3)
  

где вызовы столбцов S и T определяют верхний и нижний диапазоны для окна, но я хотел бы использовать R по, ну, причинам.

Пример данных:

 type    start   end seqid   score   strand
m6A 2   2   NC_002932.3 44  -
modified_base   20  20  NC_002932.3 41  -
m6A 57  57  NC_002932.3 451 -
modified_base   69  69  NC_002932.3 55   
m6A 80  80  NC_002932.3 540  
modified_base   93  93  NC_002932.3 55   
m4C 139 139 NC_002932.3 37   
m6A 196 196 NC_002932.3 422  
m4C 200 200 NC_002932.3 40   
m6A 204 204 NC_002932.3 571 -
m6A 210 210 NC_002932.3 477 -
m6A 255 255 NC_002932.3 500 -
modified_base   264 264 NC_002932.3 32   
  

Желаемый результат из приведенного выше:
0-200 1
200-400 1

Реальные файлы содержат десятки тысяч строк. Заранее спасибо за любую помощь. У меня есть данные в виде файлов, разделенных вкладками, которые я бы с радостью прочитал в любой форме, чтобы получить то, что я хочу, но играл с data.frame, потому что это то, что я знаю до сих пор.

Ответ №1:

Вот dplyr подход:

 library(dplyr)
df2 <- df %>%
  group_by(grp = start %/% 200   1) %>%
  summarize(min = min(start),
            max = max(start),
            count = sum(type == "m4C")) 
#> df2
## A tibble: 2 x 4
#    grp   min   max count
#  <dbl> <dbl> <dbl> <int>
#1     1     2   196     1
#2     2   200   264     1



# additional step to match output more closely
df2 %>%
  mutate(group = paste0(min, "-", max)) %>%
  select(group, count)

## A tibble: 2 x 2
#  group   count
#  <chr>   <int>
#1 2-196       1
#2 200-264     1
  

Загрузка данных:

 df <- read.table(
  header = T, 
  stringsAsFactors = F,
  text = "type    start   end seqid   score   strand
m6A 2   2   NC_002932.3 44  -
modified_base   20  20  NC_002932.3 41  -
m6A 57  57  NC_002932.3 451 -
modified_base   69  69  NC_002932.3 55   
m6A 80  80  NC_002932.3 540  
modified_base   93  93  NC_002932.3 55   
m4C 139 139 NC_002932.3 37   
m6A 196 196 NC_002932.3 422  
m4C 200 200 NC_002932.3 40   
m6A 204 204 NC_002932.3 571 -
m6A 210 210 NC_002932.3 477 -
m6A 255 255 NC_002932.3 500 -
modified_base   264 264 NC_002932.3 32   ")