Home > OS >  Paste string when NA in another column
Paste string when NA in another column

Time:12-07

Here's an example of my data :

my_df <- data.frame("R" = c("123", NA, NA, "456", "789", "123", NA),
                "D" = c("abc", "def", "ghi", "jkl", "mno", "aze", "aze"),
                stringsAsFactors = FALSE)

What I'd like to do is whenever I have NA in the column "R" I want to paste the content in the column "D" in the last previous row where "R" was not NA.

Here's the expected result :

my_result <- data.frame("R" = c("123", "456", "789", "123"),
                    "D" = c("abcdefghi", "ijk", "lmn", "azeaze"),
                    stringsAsFactors = FALSE)

CodePudding user response:

tidyverse

my_df <- data.frame("R" = c("123", NA, NA, "456", "789", "123", NA),
                    "D" = c("abc", "def", "ghi", "jkl", "mno", "aze", "aze"),
                    stringsAsFactors = FALSE)


library(tidyverse)
my_df %>%
  mutate(grp = cumsum(!is.na(R))) %>% 
  fill(R) %>%
  group_by(R, grp) %>%
  summarise(D = paste0(D, collapse = ""), .groups = "drop") %>% 
  arrange(grp) %>% 
  select(-grp)

#> # A tibble: 4 x 2
#>   R     D        
#>   <chr> <chr>    
#> 1 123   abcdefghi
#> 2 456   jkl      
#> 3 789   mno      
#> 4 123   azeaze

Created on 2021-12-07 by the reprex package (v2.0.1)

data.table

library(data.table)
library(magrittr)

setDT(my_df)[, grp := cumsum(!is.na(R))] %>% 
  .[, R := zoo::na.locf(R)] %>% 
  .[, list(D = paste0(D, collapse = "")), by = list(R, grp)] %>% 
  .[, grp := NULL] %>% 
  .[]

#>      R         D
#> 1: 123 abcdefghi
#> 2: 456       jkl
#> 3: 789       mno
#> 4: 123    azeaze

Created on 2021-12-07 by the reprex package (v2.0.1)

CodePudding user response:

You can use paste in sapply after you have split my_df$D by cumsum(!is.na(my_df$R)).

i <- !is.na(my_df$R)
data.frame(my_df["R"][i,,drop=FALSE]
         , D = sapply(split(my_df$D, cumsum(i)), paste, collapse = ""))
#    R         D
#1 123 abcdefghi
#4 456       jkl
#5 789       mno
#6 123    azeaze
  • Related