Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign ID to column with NA's

This must be easy but my brain is blocked!

I have this dataframe:

   col1 
   <chr>
 1 A    
 2 B    
 3 NA   
 4 C    
 5 D    
 6 NA   
 7 NA   
 8 E    
 9 NA   
10 F    
df <- structure(list(col1 = c("A", "B", NA, "C", "D", NA, NA, "E", 
NA, "F")), row.names = c(NA, -10L), class = c("tbl_df", "tbl", 
"data.frame"))

I want to add a column with uniqueID only for values that are not NA with tidyverse.

Expected output:

   col1  uniqueID
   <chr>    <dbl>
 1 A            1
 2 B            2
 3 NA          NA
 4 C            3
 5 D            4
 6 NA          NA
 7 NA          NA
 8 E            5
 9 NA          NA
10 F            6

I have tried: n(), row_number(), cur_group_id ....

like image 864
TarJae Avatar asked Dec 18 '22 11:12

TarJae


2 Answers

We could do this easily in data.table. Specify the condition in i i.e. non-NA elements in 'col1', create the column 'uniqueID' with the sequence of elements by assignment (:=)

library(data.table)
setDT(df)[!is.na(col1), uniqueID := seq_len(.N)]

-output

df
    col1 uniqueID
 1:    A        1
 2:    B        2
 3: <NA>       NA
 4:    C        3
 5:    D        4
 6: <NA>       NA
 7: <NA>       NA
 8:    E        5
 9: <NA>       NA
10:    F        6

In dplyr, we can use replace

library(dplyr)
df %>%
     mutate(uniqueID = replace(col1, !is.na(col1), 
             seq_len(sum(!is.na(col1)))))

-output

# A tibble: 10 x 2
   col1  uniqueID
   <chr> <chr>   
 1 A     1       
 2 B     2       
 3 <NA>  <NA>    
 4 C     3       
 5 D     4       
 6 <NA>  <NA>    
 7 <NA>  <NA>    
 8 E     5       
 9 <NA>  <NA>    
10 F     6  
like image 51
akrun Avatar answered Dec 20 '22 01:12

akrun


Another approach:

library(dplyr)
df %>% 
  mutate(UniqueID = cumsum(!is.na(col1)), 
         UniqueID = if_else(is.na(col1), NA_integer_, UniqueID))

# A tibble: 10 x 2
   col1  UniqueID
   <chr>    <int>
 1 A            1
 2 B            2
 3 NA          NA
 4 C            3
 5 D            4
 6 NA          NA
 7 NA          NA
 8 E            5
 9 NA          NA
10 F            6
like image 45
Karthik S Avatar answered Dec 20 '22 02:12

Karthik S