code123 - 1 year ago 63
R Question

Conditional replacement of NAs in two rasters of same dimensions R

This question is linked to Conditional replacement of NAs in two dataframes R but I would like to do the same thing on a raster instead of converting

`df1`
and
`df2`
to dataframes.

Given two rasters (
`df1,df2`
) of equal dimensions:

``````df1: dimensions  : 510, 1068, 544680, 1  (nrow, ncol, ncell, nlayers)

df2: dimensions  : 510, 1068, 544680, 1  (nrow, ncol, ncell, nlayers)
``````

How can one find all columns in
`df1`
where all rows are
`NAs`
, go to
`df2`
and set all values in matching columns to
`NAs`
?

First, the manner in which the OP generated the sample data in his comment to dracodoc is inconsistent with the OP's question:

``````library(raster)
r <- raster(nrow=5, ncol=5)
df1 <- stack( sapply(1:5, function(i) setValues(r, rnorm(ncell(r), i, 3))))
df2<- stack( sapply(1:5, function(i) setValues(r, rnorm(ncell(r), i, 3))))
df1[1,]<-NA
``````

This will set the first row of each layer of `df1` to `NA`. The question then should be:

How can one find all rows in `df1` where all columns are `NA`s, go to `df2` and set all values in matching rows to `NA`s?

I will answer this question first and then address the complement problem of:

How can one find all columns in `df1` where all rows are `NA`s, go to `df2` and set all values in matching columns to `NA`s?

which is the OP's original question.

Set rows that are `NA` in `df1` to `NA` in `df2`

To answer the first question, simulate another example dataset with different numbers for layers, rows, and columns; then, set different rows in each layer of `df1` to `NA`:

``````set.seed(123) ## only for full reproducibility
library(raster)
r <- raster(nrow=7, ncol=5)  ## 7 rows to differentiate from 5 columns
nlayers <- 6
df1 <- stack(sapply(1:nlayers, function(i) setValues(r, rnorm(ncell(r), i, 3))))
df2<- stack(sapply(1:nlayers, function(i) setValues(r, rnorm(ncell(r), i, 3))))
df1[[1]][1,]<-NA  ## set row 1 of layer 1 to NA
df1[[1]][2,]<-NA  ## set row 2 of layer 1 to NA
df1[[2]][2,]<-NA  ## set row 2 of layer 2 to NA
df1[[3]][2,]<-NA  ## set row 2 of layer 3 to NA
df1[[4]][5,]<-NA  ## set row 5 of layer 4 to NA
df1[[5]][5,]<-NA  ## set row 5 of layer 5 to NA
df1[[6]][3,]<-NA  ## set row 3 of layer 6 to NA
``````

Note that `df1` looks like:

``````df1[]
##         layer.1    layer.2    layer.3    layer.4    layer.5   layer.6
## [1,]         NA  4.0659208  1.5269065  3.8649168  7.1053530  2.712011
## [2,]         NA  3.6617530 -3.9275066  1.6452866  4.2134075  6.113365
## [3,]         NA  1.8142649  6.0172156 -1.0038258  0.2835675  6.931442
## [4,]         NA  1.0821120  0.8723977  2.8593204  0.4559970  7.309570
## [5,]         NA  0.8585870  0.9359742  6.7569898  0.1953915  4.624904
## [6,]         NA         NA         NA  2.2739591  3.4072804  2.810022
## [7,]         NA         NA         NA  5.8238930  0.6147332  9.789556
## [8,]         NA         NA         NA -0.8536481  7.0637503  4.951049
## [9,]         NA         NA         NA  3.8333141 11.3003268  3.403461
##[10,]         NA         NA         NA  5.5582216  1.1389086  5.291161
##[11,]  4.6722454 -1.3693257  3.0172926  4.9034601  7.3632165        NA
##[12,]  2.0794415  0.7913455  4.1558412  4.3170286  7.3071267        NA
##[13,]  2.2023144  0.6000339  1.8880199  2.0778820  5.9966077        NA
##[14,]  1.3320481  4.3398954  4.9331296  1.4508870  1.9748702        NA
##[15,] -0.6675234  1.7498928  2.3385403  0.9276136  4.6416422        NA
##[16,]  6.3607394  2.7599555  3.9953459  4.3529398  4.1588140  6.643336
##[17,]  2.4935514  1.9143597  6.2905170  1.1575762  6.6889686  5.025942
##[18,] -4.8998515  1.8713886  4.3055445  2.5283277  3.8826837  6.283751
##[19,]  3.1040677  6.1058069  2.0222052  3.2317234  7.9309202  3.313910
##[20,] -0.4183742  1.3226870  6.4464229  9.5315860  3.8762574  2.067595
##[21,] -2.2034711  6.5494118  5.9805116         NA         NA 11.991640
##[22,]  0.3460753 -2.6462584  4.6451909         NA         NA  7.802126
##[23,] -2.0780133  3.7538412  3.7161952         NA         NA  2.246186
##[24,] -1.1866737  2.3715627  1.1162818         NA         NA  4.166502
##[25,] -0.8751178  2.6478247  7.0819573         NA         NA  2.443560
##[26,] -4.0600799  3.1389184  1.1992212  8.3336526  5.8946828 12.596431
##[27,]  3.5133611  0.4930296  9.5619990  5.3545122  6.9097090  9.937239
##[28,]  1.4601194  1.0003778  7.5978319  4.1236988  3.5486581  5.204565
##[29,] -2.4144108 -1.0557261  2.2928989  2.7325095  6.5505861  7.629582
##[30,]  4.7614448 -1.2153737 -0.0792627 -2.1597417  6.1068936  4.756980
##[31,]  2.2793927  2.9105859  0.8687803  7.3940116  4.3538585  4.571259
##[32,]  0.1147856  3.3446293  3.7706511 -0.3819202  5.1958791  3.634191
##[33,]  3.6853770  2.1590127  2.2599244  6.2198425  4.8977982  4.216148
##[34,]  3.6344005  4.7668024  1.9573722  9.7273107 11.3853557 10.952722
##[35,]  3.4647432  8.1502541  0.1451443 -0.3316795  2.7759917  5.837916
``````

Note that it is now clear that each layer column in this display is a raster in row-major order.

To find the rows in `df1` that are all `NA`s in each layer, we borrow akrun's solution from the OP's linked SO question/answer, which works just as well for `Raster*` objects:

``````inds <- which(!rowSums(!is.na(df1)), arr.ind=TRUE)
##     row col
##[1,]   1   1
##[2,]   2   1
##[3,]   2   2
##[4,]   2   3
##[5,]   5   4
##[6,]   5   5
##[7,]   3   6
``````

The `which(..., arr.ind=TRUE)` returns as its first column the row and as its second column the layer in `df` that are all `NA`s. Then we can subset `df2` using a loop over layers to set those rows to `NA`:

``````## loop over layers and set the appropriate row for each layer
for (i in seq_len(nrow(inds))) df2[[inds[i,2]]][inds[i,1],] <- NA
df2[]
##        layer.1      layer.2    layer.3     layer.4    layer.5   layer.6
## [1,]          NA  7.707085465 -2.0024253  6.11057171  8.0448295 10.135710
## [2,]          NA  1.697075344  5.2094879  3.68298600 -0.9782455  7.368709
## [3,]          NA -2.079522111  4.1580797  0.22405412  3.7181621  2.593235
## [4,]          NA  0.005691694  2.2030451  9.05330712  5.3499119  4.693064
## [5,]          NA  3.456379937  3.3544335  6.73417388  2.3203773  7.038311
## [6,]          NA           NA         NA  4.71229082  6.0017088  4.058863
## [7,]          NA           NA         NA  7.65432583  6.2342898 -0.472939
## [8,]          NA           NA         NA -0.01632286  4.9008915  8.652752
## [9,]          NA           NA         NA  5.98246089 -2.3976946  3.511567
##[10,]          NA           NA         NA  2.43126287 12.7143744  4.279319
##[11,] -0.72192044  1.734304664  6.5051516  6.05123657  4.3841022        NA
##[12,]  2.85395745  5.242398488  6.1625431  3.81753414  6.9535798        NA
##[13,]  4.32954442  3.892262347  6.4357893  5.89888214  5.8212995        NA
##[14,]  3.12276506  1.659080313  1.2675960  8.00655285  8.0740197        NA
##[15,] -0.09097189 -2.598706009  9.0074482  4.02187027  7.4529783        NA
##[16,]  1.17924981  0.436648047  3.2001026  7.05267591  4.3706205  5.779332
##[17,] -1.11378939  0.530388641  8.6005555  0.43469789  6.1345033  2.494046
##[18,] -1.15165448  2.141463298 -1.0527081  1.83518668  2.1637735  4.095755
##[19,]  3.65395150  5.900596033  3.0629508  8.55765313  7.5707690  5.913475
##[20,] -2.04677774  8.879236921  6.7497437  5.13216392  3.6168850  8.012088
##[21,]  6.86588190  6.642743177  0.8542734          NA         NA  1.048360
##[22,]  0.72904122  1.600547107  0.7419331          NA         NA  4.950737
##[23,]  1.64361648 -3.269582187  0.1843839          NA         NA  8.269219
##[24,] -1.21558311  0.833660408 -0.1575398          NA         NA  4.383573
##[25,] -0.72316607  2.267621669  1.6885214          NA         NA  6.681876
##[26,] -2.95104840  4.535039012  3.9935375  5.87256242  3.2315569  7.476686
##[27,]  0.45122383  4.887583905 -3.0426315  6.87701613  2.0096578  6.803505
##[28,]  2.25694721  4.052928288  3.6359413  9.01316449  5.4334271  7.959773
##[29,]  1.97291303 -2.185823049  6.7100251  4.16805020  4.9570778  5.631874
##[30,] -1.34460946  4.548929137  9.1127221  3.84405428 -0.3708437  4.758970
##[31,] -1.36586591  0.660328351  6.9035280 -1.25971208  5.1036532 -1.929447
##[32,] -0.50659616  2.524408100  5.2703243  4.29798278  5.5706909  5.721177
##[33,]  5.48818201  2.223653532 -2.1801912  2.28444983  5.5241792  7.290854
##[34,] -2.41191086  3.284500295  1.1954799  1.07797125  1.8349489  7.606197
##[35,]  0.46284522  2.074024948  1.9438606  3.46028131  6.4283998  4.334165
``````

Set columns that are `NA` in `df1` to `NA` in `df2`

For the complement question, simulate the data set as:

``````set.seed(123) ## only for full reproducibility
library(raster)
r <- raster(nrow=7, ncol=5)
nlayers <- 6
df1 <- stack(sapply(1:nlayers, function(i) setValues(r, rnorm(ncell(r), i, 3))))
df2<- stack(sapply(1:nlayers, function(i) setValues(r, rnorm(ncell(r), i, 3))))
df1[[1]][,1]<-NA  ## set column 1 of layer 1 to NA
df1[[1]][,2]<-NA  ## set column 2 of layer 1 to NA
df1[[2]][,2]<-NA  ## set column 2 of layer 2 to NA
df1[[3]][,2]<-NA  ## set column 2 of layer 3 to NA
df1[[4]][,5]<-NA  ## set column 5 of layer 4 to NA
df1[[5]][,5]<-NA  ## set column 5 of layer 5 to NA
df1[[6]][,3]<-NA  ## set column 3 of layer 6 to NA
``````

Note that `df1` now looks like:

``````df1[]
##         layer.1     layer.2    layer.3    layer.4    layer.5   layer.6
## [1,]         NA  4.06592076  1.5269065  3.8649168  7.1053530  2.712011
## [2,]         NA          NA         NA  1.6452866  4.2134075  6.113365
## [3,]  5.6761249  1.81426487  6.0172156 -1.0038258  0.2835675        NA
## [4,]  1.2115252  1.08211201  0.8723977  2.8593204  0.4559970  7.309570
## [5,]  1.3878632  0.85858700  0.9359742         NA         NA  4.624904
## [6,]         NA -0.08412094  6.0767141  2.2739591  3.4072804  2.810022
## [7,]         NA          NA         NA  5.8238930  0.6147332  9.789556
## [8,] -2.7951837 -1.79618905 -0.6621531 -0.8536481  7.0637503        NA
## [9,] -1.0605586  8.50686790  3.5439104  3.8333141 11.3003268  3.403461
##[10,] -0.3369859  5.62388599  2.5833259         NA         NA  5.291161
##[11,]         NA -1.36932575  3.0172926  4.9034601  7.3632165  5.408472
##[12,]         NA          NA         NA  4.3170286  7.3071267  9.329761
##[13,]  2.2023144  0.60003394  1.8880199  2.0778820  5.9966077        NA
##[14,]  1.3320481  4.33989536  4.9331296  1.4508870  1.9748702  8.262161
##[15,] -0.6675234  1.74989280  2.3385403         NA         NA  4.502124
##[16,]         NA  2.75995554  3.9953459  4.3529398  4.1588140  6.643336
##[17,]         NA          NA         NA  1.1575762  6.6889686  5.025942
##[18,] -4.8998515  1.87138863  4.3055445  2.5283277  3.8826837        NA
##[19,]  3.1040677  6.10580685  2.0222052  3.2317234  7.9309202  3.313910
##[20,] -0.4183742  1.32268704  6.4464229         NA         NA  2.067595
##[21,]         NA  6.54941181  5.9805116  2.0441503  8.1581344 11.991640
##[22,]         NA          NA         NA  4.7061597  1.8524690  7.802126
##[23,] -2.0780133  3.75384125  3.7161952  4.2338825  1.2195343        NA
##[24,] -1.1866737  2.37156273  1.1162818  1.1144301 14.7231198  4.166502
##[25,] -0.8751178  2.64782471  7.0819573         NA         NA  2.443560
##[26,]         NA  3.13891845  1.1992212  8.3336526  5.8946828 12.596431
##[27,]         NA          NA         NA  5.3545122  6.9097090  9.937239
##[28,]  1.4601194  1.00037785  7.5978319  4.1236988  3.5486581        NA
##[29,] -2.4144108 -1.05572615  2.2928989  2.7325095  6.5505861  7.629582
##[30,]  4.7614448 -1.21537368 -0.0792627         NA         NA  4.756980
##[31,]         NA  2.91058592  0.8687803  7.3940116  4.3538585  4.571259
##[32,]         NA          NA         NA -0.3819202  5.1958791  3.634191
##[33,]  3.6853770  2.15901268  2.2599244  6.2198425  4.8977982        NA
##[34,]  3.6344005  4.76680240  1.9573722  9.7273107 11.3853557 10.952722
##[35,]  3.4647432  8.15025406  0.1451443         NA         NA  5.837916
``````

The solution is the same except now we use `colSums` instead of `rowSums`, and we set the column instead of the row for each layer:

``````inds <- which(!colSums(!is.na(df1)), arr.ind=TRUE)
## loop over layers and set the appropriate column for each layer
for (i in seq_len(nrow(inds))) df2[[inds[i,2]]][,inds[i,1]] <- NA
df2[]
##        layer.1      layer.2    layer.3     layer.4     layer.5   layer.6
## [1,]          NA  7.707085465 -2.0024253  6.11057171  8.04482952 10.135710
## [2,]          NA           NA         NA  3.68298600 -0.97824547  7.368709
## [3,]  4.69742764 -2.079522111  4.1580797  0.22405412  3.71816214        NA
## [4,] -0.54819149  0.005691694  2.2030451  9.05330712  5.34991185  4.693064
## [5,] -1.97752145  3.456379937  3.3544335          NA          NA  7.038311
## [6,]          NA  0.873191385  3.4021159  4.71229082  6.00170883  4.058863
## [7,]          NA           NA         NA  7.65432583  6.23428976 -0.472939
## [8,] -1.16919791  0.968248298  7.9225385 -0.01632286  4.90089152        NA
## [9,] -2.70881936  2.271489941  2.3428489  5.98246089 -2.39769458  3.511567
##[10,] -2.85414717  6.795526313  3.5041962          NA          NA  4.279319
##[11,]          NA  1.734304664  6.5051516  6.05123657  4.38410223 10.511702
##[12,]          NA           NA         NA  3.81753414  6.95357984  3.677565
##[13,]  4.32954442  3.892262347  6.4357893  5.89888214  5.82129947        NA
##[14,]  3.12276506  1.659080313  1.2675960  8.00655285  8.07401970  2.217951
##[15,] -0.09097189 -2.598706009  9.0074482          NA          NA  4.936373
##[16,]          NA  0.436648047  3.2001026  7.05267591  4.37062049  5.779332
##[17,]          NA           NA         NA  0.43469789  6.13450332  2.494046
##[18,] -1.15165448  2.141463298 -1.0527081  1.83518668  2.16377351        NA
##[19,]  3.65395150  5.900596033  3.0629508  8.55765313  7.57076903  5.913475
##[20,] -2.04677774  8.879236921  6.7497437          NA          NA  8.012088
##[21,]          NA  6.642743177  0.8542734 -2.15666846 12.25032006  1.048360
##[22,]          NA           NA         NA -0.09211236  0.04685331  4.950737
##[23,]  1.64361648 -3.269582187  0.1843839  3.39765695  3.60803827        NA
##[24,] -1.21558311  0.833660408 -0.1575398  6.59733821  7.47613959  4.383573
##[25,] -0.72316607  2.267621669  1.6885214          NA          NA  6.681876
##[26,]          NA  4.535039012  3.9935375  5.87256242  3.23155688  7.476686
##[27,]          NA           NA         NA  6.87701613  2.00965777  6.803505
##[28,]  2.25694721  4.052928288  3.6359413  9.01316449  5.43342711        NA
##[29,]  1.97291303 -2.185823049  6.7100251  4.16805020  4.95707776  5.631874
##[30,] -1.34460946  4.548929137  9.1127221          NA          NA  4.758970
##[31,]          NA  0.660328351  6.9035280 -1.25971208  5.10365320 -1.929447
##[32,]          NA           NA         NA  4.29798278  5.57069095  5.721177
##[33,]  5.48818201  2.223653532 -2.1801912  2.28444983  5.52417919        NA
##[34,] -2.41191086  3.284500295  1.1954799  1.07797125  1.83494887  7.606197
##[35,]  0.46284522  2.074024948  1.9438606          NA          NA  4.334165
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download