How to replace data in a column in R?

Viewed 51

So I have a dataframe called "myData"

print(myData) 

ID       Name      Status       AGE 
123      Mike        Yes         18
124      John        No          20
125      Lily        Yes         21
126      Jasper      No          24
127      Toby        Yes         27 
128      Will        No          19 
129      Oscar       Yes         32

I received an updated dataframe that has updated "Status" called "myData2". This dataframe has less observations than my original one and only has ID and Status.

This is the updated dataframe

print(myData2) 

ID      Status        
123      Yes                  
125      Yes         
126      Yes                  
128      No          
129      No

Is there function where I can update 'Status' column in myData with the data in myData2 using the column "ID"?

This is my desired ouput

ID       Name      Status       AGE 
123      Mike        Yes         18
124      John        No          20
125      Lily        Yes         21
126      Jasper      Yes         24
127      Toby        Yes         27 
128      Will        No          19 
129      Oscar       No          32   

2 Answers

We can use data.table join to quickly update the first dataset 'Status' with the values of second after joining on 'ID'

library(data.table)
setDT(myData)[myData2, Status := i.Status, on = .(ID)]
myData
#    ID   Name Status AGE
#1: 123   Mike    Yes  18
#2: 124   John     No  20
#3: 125   Lily    Yes  21
#4: 126 Jasper    Yes  24
#5: 127   Toby    Yes  27
#6: 128   Will     No  19
#7: 129  Oscar     No  32

In dplyr, we do a left_join and then coalesce the 'Status' columns

library(dplyr)
myData %>% 
    left_join(myData2, by = 'ID') %>% 
     mutate(Status = coalesce(Status.y, Status.x)) %>% 
     select(-Status.x, -Status.y)

data

myData <- structure(list(ID = 123:129, Name = c("Mike", "John", "Lily", 
"Jasper", "Toby", "Will", "Oscar"), Status = c("Yes", "No", "Yes", 
"No", "Yes", "No", "Yes"), AGE = c(18L, 20L, 21L, 24L, 27L, 19L, 
32L)), class = "data.frame", row.names = c(NA, -7L))

myData2 <- structure(list(ID = c(123L, 125L, 126L, 128L, 129L), Status = c("Yes", 
"Yes", "Yes", "No", "No")), class = "data.frame", row.names = c(NA, 
-5L))

Here is a base R solution using merge, i.e.,

myData$Status <- with(merge(myData,myData2,by = "ID",all.x = TRUE),
                      ifelse(is.na(Status.y),Status.x,Status.y))

such that

> myData
   ID   Name Status AGE
1 123   Mike    Yes  18
2 124   John     No  20
3 125   Lily    Yes  21
4 126 Jasper    Yes  24
5 127   Toby    Yes  27
6 128   Will     No  19
7 129  Oscar     No  32
Related