NA questionsti tidyverse

hi I am looking for a tidy verse solution to this issue

dog cat monkey rabbit angel
NA  33   33     3838    8484

if there is a "NA" in Dog, Monkey, or Cat, there needs to be an NA in all 3. Is there any easy way to do this in tidy verse? thank you!

Easier in {base}

dat <- data.frame(
  dog = c(NA, 22, NA, 11),
  cat = c(NA, 33, NA, 33),
  monkey = c(NA, 33, NA, 33),
  rabbit = c(NA, 3838, NA, 3838),
  angel = c(NA, 8484, NA, 8484))
dat
#>   dog cat monkey rabbit angel
#> 1  NA  NA     NA     NA    NA
#> 2  22  33     33   3838  8484
#> 3  NA  NA     NA     NA    NA
#> 4  11  33     33   3838  8484
dat[which(is.na(rowMeans(dat))),] <- NA
dat
#>   dog cat monkey rabbit angel
#> 1  NA  NA     NA     NA    NA
#> 2  22  33     33   3838  8484
#> 3  NA  NA     NA     NA    NA
#> 4  11  33     33   3838  8484

hi I dont totally get what happening here

dog cat monkey rabbit angel
NA  33   33     3838    8484
88  33   23      NA    2344
38  NA  3838     NA       NA

if there is a "NA" in Dog, Monkey, or Cat, there needs to be an NA in all 3. Is there any easy way to do this in tidy verse? thank you!

it doesnt matter if there is NA in Rabbit or Angel, but if there is NA in any one of Dog, Cat, Monkey (for each row).... then the values of Dog, Cat, Monkey in that row all must be 0

Here is one way using mutate_at().

library(tidyverse)

dat <- data.frame(
  dog = c(NA, 88, 38, NA),
  cat = c(33, 33, 23, 53),
  monkey = c(33, 23, NA, NA),
  rabbit = c(3838, NA, 623, 2323),
  angel = c(8484, 8484, 3344, 8484)
  )

dat
#>   dog cat monkey rabbit angel
#> 1  NA  33     33   3838  8484
#> 2  88  33     23     NA  8484
#> 3  38  23     NA    623  3344
#> 4  NA  53     NA   2323  8484

out = dat %>%
  mutate_at(.vars =  c('dog', 'cat', 'monkey'), 
            .funs = ~ifelse(is.na(dog + cat + monkey), NA, .)
            )

out
#>   dog cat monkey rabbit angel
#> 1  NA  NA     NA   3838  8484
#> 2  88  33     23     NA  8484
#> 3  NA  NA     NA    623  3344
#> 4  NA  NA     NA   2323  8484

Created on 2022-11-22 with reprex v2.0.2.9000

rowMeans() takes the mean value of each row without removing NA values. So, if a row contains one or more NA values, rowMeans() will evaluate to NA, and is.na() will evaluate to TRUE. Then which() returns the rows which evaluate to TRUE and [ ] subsets the dataframe to include only those rows, which <- then assigns to NA.

Whether to use {base} or a {tidyverse} approach is preferable is a matter of individual taste. My preference is {base} because less syntax is required.

Missed the angels, since I'm not a Hallmarks believer.

dat <- data.frame(
  dog = c(NA, 22, NA, 11),
  cat = c(12, 33, NA, 33),
  monkey = c(12, 33, NA, 33),
  rabbit = c(15, NA, NA, 3838),
  angel = c(NA, 8484,15, 8484))
dat
#>   dog cat monkey rabbit angel
#> 1  NA  12     12     15    NA
#> 2  22  33     33     NA  8484
#> 3  NA  NA     NA     NA    15
#> 4  11  33     33   3838  8484
dat[1:4][which(is.na(rowMeans(dat[1:4]))),] <- NA
dat
#>   dog cat monkey rabbit angel
#> 1  NA  NA     NA     NA    NA
#> 2  NA  NA     NA     NA  8484
#> 3  NA  NA     NA     NA    15
#> 4  11  33     33   3838  8484

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.