在 R 中找到 FALSE 之前如何计算条件的 TRUE 值

How to count TRUE values for a condition until a FALSE is found in R

我有一个数据框,其中有一列是染色体,另一个是物理位置,最后一个是具有 TRUE 或 FALSE 值的条件。当 Position 的 i+1 值与 Position 的 i 值之差不大于某个值(示例中为 1000)时,此条件为 TRUE。

我想计算该位置的确定范围内有多少个 TRUE 值,直到找到 FALSE。

由于我的原始数据框太长,我会留下一个例子。

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)

完成此任务的最佳方法是什么?我想过使用 while 循环,但我遇到的问题是每次发现 FALSE 时它都会退出循环。我考虑过的另一件事是使用 sequence(rle),但结果与我的预期相去甚远,可能是因为我想要的更复杂。

我从 data.table::rleid 开始,但效果不佳,因为您想在之前的 TRUE 中包含一个 FALSE。相反,我最终为新组的开始设定了条件,并在该条件下使用 cumsum 来创建组索引。据我所知,在每个 CHR 组中,如果 (a) 它是第一行,(b) 如果 TRUE 前面有 [=12],则您想开始一个新组=],或 (c) 如果 FALSE 前面有 FALSE——所以我把它放在 case_when 语句中。 (写出来,条件 (b) 和 (c) 似乎可以很容易地压缩为 "the previous row is 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

您似乎在寻找位置的直方图(即计算在特定间隔内找到的位置数)。您的数组 fromto 看起来有点奇怪,因为第一个间隔是从 10 到 10。

R can do it for you 您必须使用函数的选项来控制间隔。

你好像问的是自己怎么做。您可以使用 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)
}

如果可行,请告诉我。 谢谢!

另一个选项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