K Y
K Y

Reputation: 378

Rename columns on the fly during lapply tidy

I would like to name/rename columns of a data frame / tibble on the fly during the use of lapply operations. For example:

df <- tibble(names = rep("abc",100), 
              number1 = sample(1:1000, size = 100),
              number2 = sample(10:900, size = 100),
              char_1 = sample(c("a","b","c"), size = 100, replace = TRUE), 
              number3 = round(rnorm(100, mean = 100)))
files_names <- df %>% 
  distinct(char_1 ) %>% 
  deframe %>% as.list()
names(files_names) <- files_names
lapply()
df_a <- df %>% filter(char_1 == "a")

lst_files <- lapply(files_names, function(x){
 df %>% filter(char_1 == x) %>% 
    mutate(str_glue("{x}_num3") = number3 +100)
})

Error: unexpected '=' in: " df %>% filter(char_1 == x) %>% mutate(str_glue("{x}_num3") =" }) Error: unexpected '}' in "}"

In this example, I use mutate function and of course, I get an error,

but generally, I need to use select/rename or mutate operations inside the lapply

with preferably the combination of str_glue function or paste. Thank you for your time!

Upvotes: 3

Views: 390

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389325

In base R, we can use lapply over files_names, subset df based on it, add a new column with transform and assign names using setNames

lapply(files_names, function(x) setNames(transform(subset(df, char_1 == x), 
           temp = number3 + 100), c(names(df), paste0(x,"_num3"))))

#$c
#   names number1 number2 char_1 number3 c_num3
#1    abc     463     680      c     100    200
#2    abc     244      76      c     100    200
#3    abc      14     672      c     100    200
#4    abc     603     657      c     101    201
#5    abc     709      83      c      99    199
#....

data

set.seed(123)
df <- tibble(names = rep("abc",100), 
         number1 = sample(1:1000, size = 100),
         number2 = sample(10:900, size = 100),
         char_1 = sample(c("a","b","c"), size = 100, replace = TRUE), 
         number3 = round(rnorm(100, mean = 100)))

Upvotes: 1

akrun
akrun

Reputation: 887951

We can use := for assignment here. With tidyverse, we can use map to loop over the list elements (similar to lapply from base R), then after filtering the rows based on the unique elements passed into map, create a column with mutate on the fly with the assignment operator (:=), by passing the string and evaluate (!!). The str_c does similar action as paste from base R except that its behavior is sligtly different when there are NAs

library(purrr)
library(stringr)
map(files_names, ~ 
       df %>% 
          filter(char_1 == .x) %>%
          mutate(!!str_c(.x, "_num3") := number3 + 100))

Upvotes: 3

Related Questions