Как подсчитать ИСТИННЫЕ значения для условия до тех пор, пока в R не будет найдено ЛОЖЬ - PullRequest
2 голосов
/ 08 мая 2020

У меня есть фрейм данных, в котором есть столбец для хромосомы, еще один - с физическим положением, а последний - это условие со значениями TRUE или FALSE. Это условие является ИСТИННЫМ, когда разница между значением i + 1 для Позиции и значением i для Позиции не больше определенного значения (в примере - 1000).

Я хочу подсчитать, сколько ИСТИННЫХ значений для этой позиции есть определенный диапазон, пока не будет найдено ЛОЖЬ.

Поскольку мой исходный фрейм данных слишком длинный, я оставлю пример.

CHR <- c(1,1,1,1,2,2,2,3,3,3,3)
POS <- c(10,10000,12000,15000,25,75,50000,50,100,40000,45000)
CONDITION <- c(F,T,T,F,T,F,F,T,F,T,F)
df <- data.frame(CHR,POS,CONDITION)

Я хочу что-то получить вот так:

CHR_r <- c(1,1,2,2,3,3)
from <- c(10,10000,25,50000,50,40000)
to <- c(10,15000,75,50000,100,45000)
count <- c(1,3,2,1,2,2)
result <- data.frame(CHR_r,from,to,count)

Как лучше всего выполнить sh это? Я думал об использовании while l oop, но у меня была проблема, что он выходит из l oop каждый раз, когда обнаруживается FALSE. Еще я подумал об использовании sequence(rle), но результат оказался не таким, как я ожидал, возможно, потому, что это было более сложным, чем я хотел.

Ответы [ 3 ]

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

Другой вариант с rleid

library(dplyr)
library(data.table)
df %>% 
   group_by(CHR) %>% 
   group_by(grp = pmax(rleid(pmax(CONDITION, lag(CONDITION, 
         default = first(CONDITION)))), cumsum(CONDITION)), .add = TRUE) %>%
   summarise(from = first(POS), to = last(POS), count = n())  %>% 
   ungroup %>%
   select(-grp)
# A tibble: 6 x 4
#    CHR  from    to count
#  <dbl> <dbl> <dbl> <int>
#1     1    10    10     1
#2     1 10000 15000     3
#3     2    25    75     2
#4     2 50000 50000     1
#5     3    50   100     2
#6     3 40000 45000     2
2 голосов
/ 08 мая 2020

Я начал с data.table::rleid, но это не работает, потому что вы хотите включить FALSE с предыдущим TRUE. Вместо этого я создал условие для начала новой группы и использовал cumsum для этого условия для создания индексов группы. Насколько я могу судить, внутри каждой группы CHR вы хотите создать новую группу, если (а) это первая строка, (б) если есть TRUE, которому предшествует FALSE, или (c), если есть FALSE, которому предшествует FALSE - поэтому я помещаю это в оператор case_when. (Записывая это, кажется, что условия (b) и (c) можно легко сжать до "предыдущая строка FALSE" , но я оставлю как есть на случай, если отсутствуют значения или что-то в этом роде.)

library(dplyr)
df %>%
  group_by(CHR) %>%
  mutate(group_break = case_when(
    row_number() == 1 ~ 1,
    CONDITION & !lag(CONDITION, 1) ~ 1,
    !CONDITION & !lag(CONDITION, 1) ~ 1,
    TRUE ~ 0
  ),
  group_ind = cumsum(group_break)
  ) %>%
  group_by(CHR, group_ind) %>%
  summarize(from = first(POS), to = last(POS), count = n())
# # A tibble: 6 x 5
# # Groups:   CHR [3]
#     CHR group_ind  from    to count
#   <dbl>     <dbl> <dbl> <dbl> <int>
# 1     1         1    10    10     1
# 2     1         2 10000 15000     3
# 3     2         1    25    75     2
# 4     2         2 50000 50000     1
# 5     3         1    50   100     2
# 6     3         2 40000 45000     2
0 голосов
/ 08 мая 2020

Кажется, вы ищете гистограмму позиций (т.е. подсчитайте, сколько позиций найдено в определенных c интервалах). Ваши массивы from и to кажутся немного странными, поскольку первый интервал составляет от 10 до 10.

R может сделать это за вас , вам нужно будет контролировать интервалы с помощью параметры функции.

Кажется, вы спрашиваете, как это сделать самому. Вы можете использовать функцию which для проверки ваших массивов. Попробуйте использовать этот код после того, что вы задали в своем вопросе

count_of=c(0,length(from))
for  (i in c(1:length(from))){
  ind=which(POS>from[i] & POS<to[i]) 
  count_of[i]=length(ind)
}

Сообщите мне, работает ли это. Спасибо!

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