Home > OS >  Extracting specific variable names into a single variable
Extracting specific variable names into a single variable

Time:03-18

I would to pick out any variable with ## in each row then store such variables in the vars_extract variable. Any idea?

library(tidyverse)

df <- tibble(
  "a1" = c("##", 3, NA, 4, 5),
  "a2" = c(10, 38, "##", 4, 5),
  "a3" = c(11, 34, NA, 4, 5),
  "a4" = c("##", 35, 67, 4, "##"),
  "fname" = c("Megan", "John", "Terry", "Kim", "Anne")
)

# Trial (though not modified)
df %>%
  mutate(vars_extract = names(.))

I would like to something like this

for Anne, I have vars_extract as "a1, a4"

CodePudding user response:

Something like this?

library(dplyr)
library(tidyr)

df %>%
  mutate(across(a1:a4, ~case_when(. == '##' ~ cur_column()), .names = 'new_{col}')) %>%
  unite(New_Col, starts_with('new'), na.rm = TRUE, sep = ' ')
 a1    a2       a3 a4    fname New_Col
  <chr> <chr> <dbl> <chr> <chr> <chr>  
1 ##    10       11 ##    Megan "a1 a4"
2 3     38       34 35    John  ""     
3 NA    ##       NA 67    Terry "a2"   
4 4     4         4 4     Kim   ""     
5 5     5         5 ##    Anne  "a4"   

CodePudding user response:

A base R solution:

df$New_Col <- apply(df == '##', 1, \(x) ifelse(any(x), toString(names(which(x))), NA))

# A tibble: 5 x 6
  a1    a2       a3 a4    fname New_Col
  <chr> <chr> <dbl> <chr> <chr> <chr>  
1 ##    10       11 ##    Megan a1, a4 
2 3     38       34 35    John  NA     
3 NA    ##       NA 67    Terry a2     
4 4     4         4 4     Kim   NA     
5 5     5         5 ##    Anne  a4    

CodePudding user response:

Using the Compose function from the functional package we can do this:

df %>% mutate(vars_extract = lapply(apply(df, 1, function(x) which(x=="##")), Compose(names, unlist, function(x)paste(x, collapse = ", "))))

CodePudding user response:

Another possible solution, based on purrr::pmap_chr:

library(tidyverse)
      
pmap_chr(df, ~  names(list(...))[list(...) == "##"] %>% na.omit %>% 
               str_c(collapse = ", ")) %>% bind_cols(df, New_Col = .)

#> # A tibble: 5 × 6
#>   a1    a2       a3 a4    fname New_Col 
#>   <chr> <chr> <dbl> <chr> <chr> <chr>   
#> 1 ##    10       11 ##    Megan "a1, a4"
#> 2 3     38       34 35    John  ""      
#> 3 <NA>  ##       NA 67    Terry "a2"    
#> 4 4     4         4 4     Kim   ""      
#> 5 5     5         5 ##    Anne  "a4"
  • Related