我有一个包含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
我将感谢你的帮助。
萨巴
答案 0 :(得分:3)
您可以像在矢量中一样利用矩阵中的矢量化。给定矩阵x
,x[, -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
如何运作的解释:
逻辑是覆盖两个矩阵:
x[, -1]
,这是原始矩阵没有第一列。这是可以更改的所有数据。第一列永远不会改变,因为左边没有任何内容。x[, -ncol(x)]
,这是原始矩阵没有最后一列。这是可以发出变化信号的所有数据。最后一栏永远不会发出变化的信号,因为它没有任何正确的内容。这两个矩阵具有相同的维度,因此,如果重叠,将对可以发出变化信号的单元格(矩阵2)与它们可能发生变化的单元格(矩阵1)进行对齐。
通过调用x[, -1][x[, -ncol(x)] == 1]
,我们要求第一个矩阵中的所有单元格(所有可能变化的单元格),只要第二个矩阵中的单元格(所有信令单元格)等于1。
<- 1
通过为这些单元格指定值1来完成此操作。
答案 1 :(得分:2)
一个选项是使用which
和arr.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)
将apply
与dplyr
包中的某些辅助函数一起使用,您可以将矩阵移到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()