Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill NA's in a column if the column contains a number but leave NA if a column is all NAs

Tags:

r

dplyr

tidyr

I am creating a file for running in a model with species counts at a number of different sites that we visited multiple times. However, not all the sites were visited every visit.

I need a column to remain all NA's if it was not visited but should have a 0 if it was from a plot that was visited but the species was not detected. Below is a mini sample of my data in the format I currently have it in. So I essentially need a way to convert all the NA's in column p1 and p2 to 0 while keep p3 for the 2nd visit all NA's. I have hundreds of columns in my real data so I would prefer to not have to manually assign whether NA's should convert to 0 or remain NA if possible column by column.

    ## creates example dataframe
library(dplyr)
library(tidyr)

Species<-c("a","b","c","a","d","d","c","a","b","c") # four species
visit<-c(1,1,2,2,1,2,2,1,2,1) #two visits
Site<-c("p1","p1","p1","p1","p2","p2","p2","p3","p2","p2") #three sites
TotalCount<-c(1,3,4,3,5,2,1,3,1,1) $number of individuals captured
df<-data.frame(Species, visit, Site, TotalCount)

df2 <- df %>% 
  dplyr::select("Species", "Site","TotalCount","visit") %>%
  pivot_wider(names_from = Site, values_from = TotalCount, 
             values_fill = NA)%>%
arrange(visit, Species)

final df2 data frame should look like this:

   Species  visit   p1    p2    p3
1  a           1     1     0     3
2  b           1     3     0     0
3  c           1     0     1     0
4  d           1     0     5     0
5  a           2     3     0    NA
6  b           2     0     1    NA
7  c           2     4     1    NA
8  d           2     0     2    NA
like image 893
Amanda Goldberg Avatar asked Oct 24 '25 21:10

Amanda Goldberg


2 Answers

I believe this accomplishes the task using package hutilscpp

library(hutilscpp)

df2 %>%
  group_by(visit) %>%
  mutate_all(.funs = \(x) if (allNA(x)) x else coalesce0(x))
like image 158
Hugh Avatar answered Oct 28 '25 05:10

Hugh


df2 %>%
  mutate(across(starts_with("p"), ~ NA^(!length(na.omit(.))) * nafill(., fill = 0)), .by = visit)

gives

# A tibble: 8 × 5
  Species visit    p1    p2    p3
  <chr>   <dbl> <dbl> <dbl> <dbl>
1 a           1     1     0     3
2 b           1     3     0     0
3 c           1     0     1     0
4 d           1     0     5     0
5 a           2     3     0    NA
6 b           2     0     1    NA
7 c           2     4     1    NA
8 d           2     0     2    NA
like image 44
ThomasIsCoding Avatar answered Oct 28 '25 05:10

ThomasIsCoding



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!