用“1”替换下一个值

时间:2016-09-23 02:04:51

标签: r

我有一个包含1565行和132列的矩阵。所有观察结果都是“0”或“1”。现在我想保持所有观察结果相同但只有一个变化,即只要有“1”,同一行中的下一个值应该变为“1”。请参见下面的示例:

>df
 0    0    1    0    0
NA    0    1    1    0
 0    1    0    0    NA

我想要的是:

 0    0    1    1    0
NA    0    1    1    1
 0    1    1    0    NA

我将感谢你的帮助。

萨巴

4 个答案:

答案 0 :(得分:3)

您可以像在矢量中一样利用矩阵中的矢量化。给定矩阵xx[, -1][x[, -ncol(x)] == 1] <- 1执行您所追求的内容。以下示例和说明:

# Create sample matrix
set.seed(100)
x <- sample(c(0, 1, NA), 100, replace = TRUE)
x <- matrix(x, ncol = 10)

# Examine before replacement
x
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#>  [1,]    0    1    1    1    0    0    1    1    1    NA
#>  [2,]    0   NA   NA   NA   NA    0    1    0    1     0
#>  [3,]    1    0    1    1   NA    0   NA    1   NA     1
#>  [4,]    0    1   NA   NA   NA    0   NA   NA   NA     1
#>  [5,]    1   NA    1   NA    1    1    1    1    0    NA
#>  [6,]    1   NA    0   NA    1    0    1    1    1     1
#>  [7,]   NA    0   NA    0   NA    0    1   NA   NA     1
#>  [8,]    1    1   NA    1   NA    0    1   NA    0     0
#>  [9,]    1    1    1   NA    0    1    0   NA    0     0
#> [10,]    0   NA    0    0    0    0   NA    0   NA    NA

# Replace any cell right-of-1 with 1
x[, -1][x[, -ncol(x)] == 1] <- 1

# Examine after replacement
x
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#>  [1,]    0    1    1    1    1    0    1    1    1     1
#>  [2,]    0   NA   NA   NA   NA    0    1    1    1     1
#>  [3,]    1    1    1    1    1    0   NA    1    1     1
#>  [4,]    0    1    1   NA   NA    0   NA   NA   NA     1
#>  [5,]    1    1    1    1    1    1    1    1    1    NA
#>  [6,]    1    1    0   NA    1    1    1    1    1     1
#>  [7,]   NA    0   NA    0   NA    0    1    1   NA     1
#>  [8,]    1    1    1    1    1    0    1    1    0     0
#>  [9,]    1    1    1    1    0    1    1   NA    0     0
#> [10,]    0   NA    0    0    0    0   NA    0   NA    NA

x[, -1][x[, -ncol(x)] == 1] <- 1如何运作的解释:

逻辑是覆盖两个矩阵:

  1. x[, -1],这是原始矩阵没有第一列。这是可以更改的所有数据。第一列永远不会改变,因为左边没有任何内容。
  2. x[, -ncol(x)],这是原始矩阵没有最后一列。这是可以发出变化信号的所有数据。最后一栏永远不会发出变化的信号,因为它没有任何正确的内容。
  3. 这两个矩阵具有相同的维度,因此,如果重叠,将对可以发出变化信号的单元格(矩阵2)与它们可能发生变化的单元格(矩阵1)进行对齐。

    通过调用x[, -1][x[, -ncol(x)] == 1],我们要求第一个矩阵中的所有单元格(所有可能变化的单元格),只要第二个矩阵中的单元格(所有信令单元格)等于1。

    <- 1通过为这些单元格指定值1来完成此操作。

答案 1 :(得分:2)

一个选项是使用whicharr.ind=TRUE来获取行/列索引,将1添加到列索引,将值子集化并将其更改为1.

i1 <- which(df==1, arr.ind=TRUE)
i1[,2] <- i1[,2]+1
df[i1] <- 1
df
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    1    1    0
#[2,]   NA    0    1    1    1
#[3,]    0    1    1    0   NA

如果NA旁边有NA元素并希望将其保留为NA,那么我们可以用

修改上面的代码
df[i1] <- replace(df[i1], !is.na(df[i1]), 1)

数据

df <- structure(c(0L, NA, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 
 0L, NA), .Dim = c(3L, 5L), .Dimnames = list(NULL, NULL))

答案 2 :(得分:1)

applydplyr包中的某些辅助函数一起使用,您可以将矩阵移到1右侧,然后or|)使用原始矩阵,自1 | (1,0,NA) = 1起,这会将1之后的值转换为1;使用coalesce函数将移位矩阵中的所有NA转换为0,以避免0转换为NA

library(dplyr)
t(apply(mat, 1, function(r) as.integer(r | lag(coalesce(r, 0L), default = 0))))

#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    1    1    0
#[2,]   NA    0    1    1    1
#[3,]    0    1    1    0   NA

或者您可以使用基数R:

t(apply(mat, 1, function(r) as.integer(r | c(0, replace(r[-length(r)], 
                                                        is.na(r[-length(r)]), 0)))))

#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    1    1    0
#[2,]   NA    0    1    1    1
#[3,]    0    1    1    0   NA

答案 3 :(得分:0)

假设先前的修改col-to-col不算作正信号。

set.seed(1)
nr    = 1565
nc    = 132
input = matrix(sample(c(0,1),nr*nc,replace=TRUE),nrow = nr,ncol=nc)
makeNext1 = function(){
  out = input
  for(ixCol in c(1:(nc-1))){
    ix = which(input[,ixCol] == 1)
    if(length(ix) > 0)
      out[ix,ixCol + 1] = 1
  }
  out
}
result = makeNext1()