Сопоставить функцию с несколькими фреймами данных - PullRequest
0 голосов
/ 03 октября 2018

У меня есть функция, которая создает новый столбец в кадре данных, повторяя имя кадра данных в каждой ячейке:

add_column_with_name <- function(x) {
    x$name <- deparse(substitute(x))
    return(x)

Работает отдельно:

df_y <- tibble(x = c(1,2,3,4), y = c('a', 'b', 'c', 'd'))
df_y <- add_columns_with_name(df_y)
df_y
# A tibble: 4 x 3
  x y     name1
<dbl> <chr> <chr>
1     1 a     df_y 
2     2 b     df_y 
3     3 c     df_y 
4     4 d     df_y 

Но объектимя не отображается, когда я передаю функцию в качестве аргумента для отображения, чтобы применить ее к списку фреймов данных:

df_x <- tibble(x = c(5,6,7,8), y = c('e', 'f', 'g', 'h'))
df_vector <- c(df_x, df_y)
result <- map_df(df_vector, add_column_with_name) 
result

# A tibble: 8 x 3
      x y     name1  
   <dbl> <chr> <chr>  
1     5 e     .x[[i]]
2     6 f     .x[[i]]
3     7 g     .x[[i]] 
4     8 h     .x[[i]]
5     1 a     .x[[i]]
6     2 b     .x[[i]]
7     3 c     .x[[i]]
8     4 d     .x[[i]]

Я также попробовал более элегантный подход:

result <- map_df(df_vector, ~ mutate(., name = deparse(substitute(.))))
result

# A tibble: 8 x 3
  x y     name 
<dbl> <chr> <chr>
1     5 e     .    
2     6 f     .    
3     7 g     .    
4     8 h     .    
5     1 a     .    
6     2 b     .    
7     3 c     .    
8     4 d     .

Я мог бы жестко закодировать значения за то время, которое понадобилось мне, чтобы написать этот пост, но я думаю, что упускаю что-то важное!Возможно ли, что ошибка заключается в использовании deparse (substitute ())?

Спасибо

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Вы можете запретить оценку df_x и df_y с помощью цитаты:

purrr::map_df(list(quote(df_x),quote(df_y))
         , function(x) {y <- eval(x); y$name <- as.character(x); y})
## A tibble: 8 x 3
#      x y     name 
#  <dbl> <chr> <chr>
#1     5 e     df_x 
#2     6 f     df_x 
#3     7 g     df_x 
#4     8 h     df_x 
#5     1 a     df_y 
#6     2 b     df_y 
#7     3 c     df_y 
#8     4 d     df_y
0 голосов
/ 03 октября 2018

Это решение работает, если вы используете names для list элементов:

df_y <- tibble(x = c(1,2,3,4), y = c('a', 'b', 'c', 'd'))
df_x <- tibble(x = c(5,6,7,8), y = c('e', 'f', 'g', 'h'))

df_list <- list(df_y, df_x) # we create the list

names_list <- c("df_y", "df_x") # we need to name each element 

map2(df_list, names_list, function(x,y) {x$name = y # assignment
                                         x}) 

Итак, вам просто нужно создать вектор имен каждого data.frame.Затем используйте map2, который отображает функцию на два вектора (x,y)

Выход:

$`df_y`
# A tibble: 4 x 3
      x y     name 
  <dbl> <chr> <chr>
1     1 a     df_y 
2     2 b     df_y 
3     3 c     df_y 
4     4 d     df_y 

$df_x
# A tibble: 4 x 3
      x y     name 
  <dbl> <chr> <chr>
1     5 e     df_x 
2     6 f     df_x 
3     7 g     df_x 
4     8 h     df_x 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...