如何找到具有相同值的三个连续行

时间:2015-12-13 10:57:31

标签: r

我的数据框如下:

chr     leftPos    Sample1  X.DD   3_samples    MyStuff
1        324         -1        1        1           1
1        4565        -1        0        0           0 
1        6887        -1        1        0           0
1        12098        1       -1        1           1
2        12          -1        1        0           1
2        43          -1        1        1           1
5        1           -1        1        1           0
5        43           0        1       -1           0
5        6554         1        1        1           1
5        7654        -1        0        0           0
5        8765         1        1        1           0
5        9833         1        1        1          -1
6        12           1        1        0           0
6        43           0        0        0           0
6        56           1        0        0           0
6        79           1        0       -1           0
6        767          1        0       -1           0
6        3233         1        0       -1           0

我想根据以下规则进行转换 对于每条染色体:

一个。如果一列中连续有三个或更多1或-1,那么该值保持不变。

湾如果一列中连续少于三个1或-1,则1或-1的值变为0

列中的行必须具有相同的符号(+或-ve)才能称为连续符号。

上述数据框的结果应为:

chr     leftPos    Sample1  X.DD   3_samples    MyStuff
    1        324         -1        0        0           0
    1        4565        -1        0        0           0 
    1        6887        -1        0        0           0
    1        12098        0        0        0           0
    2        12           0        0        0           0
    2        43           0        0        0           0
    5        1            0        1        0           0
    5        43           0        1        0           0
    5        6554         0        1        0           0
    5        7654         0        0        0           0
    5        8765         0        0        0           0
    5        9833         0        0        0           0
    6        12           0        0        0           0
    6        43           0        0        0           0
    6        56           1        0        0           0
    6        79           1        0       -1           0
    6        767          1        0       -1           0
    6        3233         1        0       -1           0

我已设法连续两行执行此操作,但我不知道如何更改三行或更多行。

DAT_list2res <-cbind(DAT_list2[1:2],DAT_list2res)
colnames(DAT_list2res)[1:2]<-c("chr","leftPos")
DAT_list2res$chr<-as.numeric(gsub("chr","",DAT_list2res$chr))
DAT_list2res<-as.data.frame(DAT_list2res)
dx<-DAT_list2res
f0 <- function( colNr, dx)
{
  col <- dx[,colNr]
  n1 <- which(col == 1| col == -1)          # The `1`-rows.
  d0 <- which( diff(col) == 0)      # Consecutive rows in a column are equal.
  dc0 <- which( diff(dx[,1]) == 0)  # Same chromosome.
  m <- intersect( n1-1, intersect( d0, dc0 ) )
  return ( setdiff( 1:nrow(dx), union(m,m+1) ) )
}
g <- function( dx )
{
  for ( i in 3:ncol(dx) ) { dx[f0(i,dx),i] <- 0 }  
  return ( dx )
}
dx<-g(dx)

2 个答案:

答案 0 :(得分:4)

以下是仅使用基础R的一种解决方案。

首先定义一个函数,它将替换任何小于3的重复:

replace_f <- function(x){
  subs <- rle(x)
  subs$values[subs$lengths < 3] <- 0
  inverse.rle(subs)
}

然后将data.frame拆分为chr,然后将该函数应用于您要更改的所有列(在本例中为第3列到第6列):

df[,3:6] <- do.call("rbind", lapply(split(df[,3:6], df$chr), function(x) apply(x, 2, replace_f)))

请注意,在替换原始数据之前,我们会将结果与rbind结合使用。这将为您提供所需的结果:

   chr leftPos Sample1 X.DD X3_samples MyStuff
1    1     324      -1    0          0       0
2    1    4565      -1    0          0       0
3    1    6887      -1    0          0       0
4    1   12098       0    0          0       0
5    2      12       0    0          0       0
6    2      43       0    0          0       0
7    5       1       0    1          0       0
8    5      43       0    1          0       0
9    5    6554       0    1          0       0
10   5    7654       0    0          0       0
11   5    8765       0    0          0       0
12   5    9833       0    0          0       0
13   6      12       0    0          0       0
14   6      43       0    0          0       0
15   6      56       1    0          0       0
16   6      79       1    0         -1       0
17   6     767       1    0         -1       0
18   6    3233       1    0         -1       0

答案 1 :(得分:2)

使用$("#go").on("click",function(){ goOnePixelRight(); }); function goOnePixelRight(){ var top=$(".move").offset().top; var left=$(".move").offset().left; $(".move").offset({top:top,left:left+1}); if(parseInt($(".move").offset().left)!=parseInt($(".stop").offset().left)){ setTimeout("goOnePixelRight();",1000); } } 的{​​{1}}解决方案

data.table

这使用rleidrequire(data.table) setDT(dat) dat[,Sample1 := Sample1 * as.integer(.N>=3), by=.(chr, rleid(Sample1))] 有用的rleid(Sample1) - 变量进行分组。

对于您可以使用data.table语法的所有列执行此操作,如下所示:

.N

因此导致:

eval(parse(text=...))