在 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
您似乎在寻找位置的直方图(即计算在特定间隔内找到的位置数)。您的数组 from
和 to
看起来有点奇怪,因为第一个间隔是从 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
我有一个数据框,其中有一列是染色体,另一个是物理位置,最后一个是具有 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
您似乎在寻找位置的直方图(即计算在特定间隔内找到的位置数)。您的数组 from
和 to
看起来有点奇怪,因为第一个间隔是从 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