Переименуйте столбцы на лету во время лаконичной приборки - PullRequest
3 голосов
/ 07 ноября 2019

Я хотел бы назвать / переименовать столбцы фрейма данных / таблицы на лету во время использования операций lapply. Например:

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 "}"

В этом примере я использую функцию mutate и, конечно, получаю ошибку,

но, как правило, мне нужно использовать операции выбора / переименования или преобразования внутри laply

, предпочтительно с комбинацией функции str_glue или paste. Спасибо за ваше время.

Ответы [ 2 ]

3 голосов
/ 07 ноября 2019

Мы можем использовать := для назначения здесь. С tidyverse мы можем использовать map для циклического перебора элементов list (аналогично lapply из base R), а затем после filter строк, основанных на уникальных элементах, переданных в map,создайте столбец с mutate на лету с помощью оператора присваивания (:=), передав строку и вычислив (!!). str_c выполняет действие, аналогичное paste из base R, за исключением того, что его поведение немного отличается при наличии NA s

library(purrr)
library(stringr)
map(files_names, ~ 
       df %>% 
          filter(char_1 == .x) %>%
          mutate(!!str_c(.x, "_num3") := number3 + 100))
1 голос
/ 07 ноября 2019

В базе R мы можем использовать lapply сверх files_names, subset df на его основе, добавить новый столбец с transform и присвоить имена с помощью 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
#....

данные

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)))
...