Corey
Corey

Reputation: 435

Overwrite columns while joining dataframes in R

I have a dataframe where I needed to shift values over to the left if there were NA's present on the left. To do this, I subsetted my dataframe combine1, creating combine2 and applied the following function:

combine2 <- combine1 %>%
  select(ID, Col3:Col7)
combine2[] <-  t(apply(combine2, 1, function(x) c(x[!is.na(x)], x[is.na(x)])))

I am trying to join the two back together, keeping the shifted values from combine 2, or overwriting them over the combine1 values. I have been looking through dplyr join function, but I can't seem to find anything to make this work. Is there a way to join these two together, or possibly a way to apply that NA shifting function within the original dataframe without having to subset it out first?

This is the result of the NA shifting function:

combine1
# A tibble: 6 x 9
     ID Col1  Col2  Col3  Col4  Col5  Col6  Col7  Col8 
  <dbl> <chr> <chr> <chr> <chr> <chr> <lgl> <lgl> <chr>
1     1 text  text  P12-1 P14-5 NA    NA    NA    text 
2     2 text  text  P98-2 NA    P65-7 NA    NA    text 
3     3 text  text  NA    P53-1 NA    NA    NA    text 
4     4 text  text  P77-8 NA    NA    NA    NA    text 
5     5 text  text  NA    P58-1 P11-0 NA    NA    text 
6     6 text  text  NA    NA    P34-5 NA    NA    text 
combine2
# A tibble: 6 x 6
  ID    Col3  Col4  Col5  Col6  Col7 
  <chr> <chr> <chr> <chr> <chr> <chr>
1 1     P12-1 P14-5 NA    NA    NA   
2 2     P98-2 P65-7 NA    NA    NA   
3 3     P53-1 NA    NA    NA    NA   
4 4     P77-8 NA    NA    NA    NA   
5 5     P58-1 P11-0 NA    NA    NA   
6 6     P34-5 NA    NA    NA    NA   

Here is dput() from the dataframe:

structure(list(ID = c(1, 2, 3, 4, 5, 6), Col1 = c("text", "text", 
"text", "text", "text", "text"), Col2 = c("text", "text", "text", 
"text", "text", "text"), Col3 = c("P12-1", "P98-2", NA, "P77-8", 
NA, NA), Col4 = c("P14-5", NA, "P53-1", NA, "P58-1", NA), Col5 = c(NA, 
"P65-7", NA, NA, "P11-0", "P34-5"), Col6 = c(NA, NA, NA, NA, 
NA, NA), Col7 = c(NA, NA, NA, NA, NA, NA), Col8 = c("text", "text", 
"text", "text", "text", "text")), class = c("spec_tbl_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -6L), spec = structure(list(
    cols = list(ID = structure(list(), class = c("collector_double", 
    "collector")), Col1 = structure(list(), class = c("collector_character", 
    "collector")), Col2 = structure(list(), class = c("collector_character", 
    "collector")), Col3 = structure(list(), class = c("collector_character", 
    "collector")), Col4 = structure(list(), class = c("collector_character", 
    "collector")), Col5 = structure(list(), class = c("collector_character", 
    "collector")), Col6 = structure(list(), class = c("collector_logical", 
    "collector")), Col7 = structure(list(), class = c("collector_logical", 
    "collector")), Col8 = structure(list(), class = c("collector_character", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))```

Upvotes: 1

Views: 157

Answers (1)

lroha
lroha

Reputation: 34556

Using the code you provided, you can replace the data in a single step by indexing the left hand side:

combine1[paste0("Col", 3:7)] <- t(apply(combine1[paste0("Col", 3:7)], 1, function(x) c(x[!is.na(x)], x[is.na(x)])))

Upvotes: 1

Related Questions