从剩下的单元格给予等于0的单元格相同的值

时间:2018-01-09 19:45:07

标签: r matrix dplyr apply

我有一个矩阵,有些单元格等于0.我想要做的是给这些单元格保留在同一行的单元格中的相同值,但是在此之前的列中。

我用两个for循环解决了这个问题,但是你知道我的解决方案太慢了,因为嵌套的for循环。

这是我的小矩阵,我给了一些单元格0,以显示我的矩阵是什么样的。

 set.seed(1)
 df <- matrix(data = rnorm(n = 20, mean = 0, sd = 1), nrow = 5, ncol=4)
    df[1,2] <- 0
    df[1,3] <- 0
    df[2,3] <- 0
    df[3,4] <- 0

这是我找到的解决方案,

for(i in (1 : nrow(df))){
  for(j in (2 : ncol(df))){

    if (df[i,j] == 0){
      df[i,j] <- df[i,j-1]
    }
  }
}  

如果有人能找到比我找到的更有效的解决方案,我将非常感激。

2 个答案:

答案 0 :(得分:0)

你不需要if和第一个循环

  for(j in (2 : ncol(df))){
      df[df[,j] == 0,j] <- df[df[,j] == 0,j-1]
}  

df[,j] == 0直接为您提供满足条件的布尔向量。

           [,1]       [,2]       [,3]        [,4]
[1,] -0.6264538 -0.6264538 -0.6264538 -0.04493361
[2,]  0.1836433  0.4874291  0.4874291 -0.01619026
[3,] -0.8356286  0.7383247 -0.6212406 -0.62124058
[4,]  1.5952808  0.5757814 -2.2146999  0.82122120
[5,]  0.3295078 -0.3053884  1.1249309  0.59390132

对于data.table解决方案,更合适的解决方案是

for( i in 2:length(DT)){DT[get(names(DT)[i])==0,names(DT)[i]:= names(DT)[i-1]]}

答案 1 :(得分:0)

您可以将matrix转换为vector,将0更改为NA s(除非它们位于第一列中),然后使用zoo::na.locf转发在转换回matrix之前,非NA值。

数据:

set.seed(66)
df = matrix(data = rnorm(n = 20, mean = 0, sd = 1), nrow = 5, ncol=4)
df[1,2] = 0; df[1,3] = 0; df[2,3] = 0; df[3,4] = 0


          [,1]        [,2]       [,3]       [,4]
[1,]  2.3239747  0.00000000  0.0000000  0.1839216
[2,]  0.2169771 -0.75670339  0.0000000 -0.2920561
[3,]  0.4181927  1.22775750 -0.3114876  0.0000000
[4,] -0.1909928 -0.17795667 -1.2965404  0.1051630
[5,] -0.3148384  0.03127497 -0.9456910  0.5171277

方法:

library(zoo)
v = as.vector(t(df))
firstcol = seq(1,by=ncol(df),length.out=nrow(df))
v[-firstcol][v[-firstcol]==0] = NA
res = matrix(na.locf(v),ncol=ncol(df),byrow=T)

          [,1]        [,2]       [,3]       [,4]
[1,]  2.3239747  2.32397466  2.3239747  0.1839216
[2,]  0.2169771 -0.75670339 -0.7567034 -0.2920561
[3,]  0.4181927  1.22775750 -0.3114876 -0.3114876
[4,] -0.1909928 -0.17795667 -1.2965404  0.1051630
[5,] -0.3148384  0.03127497 -0.9456910  0.5171277