nsivakr
nsivakr

Reputation: 1595

Update multiple NA columns to 0

How to efficiently update multiple columns from NA to 0? Don't want to update all NA to 0. Only certain columns need be updated.

My current solution: Is there a better method?

dataframe$col1 = replace(dataframe$col1, is.na(dataframe$col1), 0)

dataframe$col2 = replace(dataframe$col2, is.na(dataframe$col2), 0)

dataframe$col3 = replace(dataframe$col3, is.na(dataframe$col3), 0)

Syntax used and this is not working as expected. Meaning, does not replace NA to 0.

dataframe = dataframe %>% mutate(across(c('col1', 'col2', 'col3'), ~ replace(., all(is.na(.)), 0)))

Sample Data.

structure(list(col1 = c(63755.4062, 61131.3242, 61131.3242, 192055.25, 191429.9844, 190076.4688), col2 = c(18.8754, 14.6002, 14.6002, 24.0053, 24.4012, 25.3588), col3 = c(NA, NA, NA, 45.6442, 43.9821, 47.2581)), row.names = c(NA, 6L), class = "data.frame")

Following worked. Thanks @MATT, and @Karthik.

 dataframe = dataframe %>% mutate(across(c('col1', 'col2', 'col3'), ~  ~tidyr::replace_na(., 0)))

Upvotes: 0

Views: 135

Answers (3)

Matt
Matt

Reputation: 7413

I'm not sure why Karthik's solution still returns NA for your sample data, but using replace_na from tidyr seems to work:

library(tidyr)

dataframe %>% mutate(across(c('col1', 'col2', 'col3'), ~ replace_na(., 0)))

Which gives us:

       col1    col2    col3
1  63755.41 18.8754  0.0000
2  61131.32 14.6002  0.0000
3  61131.32 14.6002  0.0000
4 192055.25 24.0053 45.6442
5 191429.98 24.4012 43.9821
6 190076.47 25.3588 47.2581

Upvotes: 1

cmoez
cmoez

Reputation: 23

The quickest way IMO would be to subset the columns you want to edit as a new dataframe, edit all NAs in the subset to 0, then overwrite your original df's selected columns.

    DFsubset <- DF[,10:12] #whichever columns
    DFsubset[is.na(DFsubset) == T] <- 0
    DF[,10:12] <- DFsubset

Upvotes: 0

Karthik S
Karthik S

Reputation: 11546

Does this work:

library(dplyr)
library(tibble)
df <- tibble(c1 = round(rnorm(10, 10,1)),
             c2 = NA_real_,
             c3 = round(rnorm(10, 10,1)),
             c4 = NA_real_,
             c5 = round(rnorm(10, 10,1)),
             c6 = NA_real_)
df
# A tibble: 10 x 6
      c1    c2    c3    c4    c5    c6
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1    12    NA    11    NA    11    NA
 2     9    NA    10    NA    10    NA
 3    11    NA    11    NA    10    NA
 4    11    NA     9    NA    10    NA
 5    10    NA     9    NA    10    NA
 6     9    NA    13    NA    12    NA
 7    10    NA    10    NA     9    NA
 8    10    NA    10    NA     9    NA
 9    11    NA    11    NA    10    NA
10    10    NA    10    NA    10    NA
df %>% mutate(across(c3:c6, ~ replace(., all(is.na(.)), 0)))
# A tibble: 10 x 6
      c1    c2    c3    c4    c5    c6
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1    12    NA    11     0    11     0
 2     9    NA    10     0    10     0
 3    11    NA    11     0    10     0
 4    11    NA     9     0    10     0
 5    10    NA     9     0    10     0
 6     9    NA    13     0    12     0
 7    10    NA    10     0     9     0
 8    10    NA    10     0     9     0
 9    11    NA    11     0    10     0
10    10    NA    10     0    10     0

Upvotes: 1

Related Questions