Невозможно установить имя листа с помощью пакета dplyr

Я экспортирую несколько фреймов данных в списке на разные листы в одном файле Excel, и я могу сделать это с помощью приведенного ниже кода (используйте mtcars в качестве примера):

library(tidyverse)
library(ImportExport)

data_list <- split(mtcars, mtcars$cyl)
table_name <- names(data_list)

# Run
excel_export(data_list, "foo.xlsx", table_names = tab_name)

И затем, я хочу сделать это по-другому, потому что я вижу, что документ dplyr сказал, что:

.y для обозначения ключа - столбец из одной строки с одним столбцом на переменную группировки, которая идентифицирует группу.

Поэтому я подумал, что .y равен моей созданной переменной table_name , и я делаю это:

data_list %>% excel_export("foo.xlsx", table_names = .y)

Тогда я получил ошибку:

Ошибка в .jcall (wb, "Lorg / apache / poi / ss / usermodel / Sheet;", "createSheet",: объект ".y" не найден

Может кто-нибудь объяснить, почему и как я могу сделать это с .y .

Любая помощь будет высоко оценена.

Всего 2 ответа


  1. Если вы ссылаетесь на цитату, я думаю, что имеет смысл использовать функцию, в которой эта цитата используется. В этом случае я нашел его в group_map (который включает group_walk , дополнительную функцию, которая работает в основном с побочным эффектом).

  2. Вам все еще нужно group_by данные. Более конкретно, он должен работать с tbl_df (не list ), как правило (но не всегда) сгруппированным тибблом.

У меня не установлено ни ImportExport ни xlsx (от которого зависит первое), поэтому я проксирую ваши действия с помощью write.csv .

library(dplyr)
mtcars %>%
  group_by(cyl) %>%
  group_walk(~ write.csv(.x, paste0(.y, ".csv")))

Побочным эффектом этого является то, что в текущем каталоге 4.csv три файла с именами 4.csv , 6.csv и 8.csv .

Если вы хотите работать с именованным списком, можно также использовать один из:

# using: data_list <- split(mtcars, mtcars$cyl)
purrr::imap(data_list,
            ~ write.csv(.x, paste0("~/Downloads/", .y, ".csv")))
Map(write.csv, data_list, paste0(names(data_list), ".csv"))

Эффект тот же.


.x и .y не являются глобальными параметрами, которые могут использоваться где угодно, они зарезервированы для определенных функций. (обычно map )

С ?map

.f Функция, формула или вектор (не обязательно атомарный).

Если формула, например ~ .x + 2, она преобразуется в функцию. Есть три способа ссылаться на аргументы:

  • Для функции с одним аргументом используйте.
  • Для функции с двумя аргументами используйте .x и .y
  • Для большего количества аргументов используйте ..1, ..2, ..3 и т. Д.

Давайте возьмем простой список

library(purrr)
listvec1 <- list(a = 1:3, b = 4:6, c = 2:4)

1) Допустим, мы хотим умножить каждый элемент в списке на 2, у map есть один аргумент, поэтому мы используем . Вот.

map(listvec1, ~. * 2)
#$a
#[1] 2 4 6

#$b
#[1]  8 10 12

#$c
#[1] 4 6 8

По совпадению .x работает и здесь:

map(listvec1, ~.x * 2)

но если вы используете .y это выдаст ошибку, потому что в map нет 2 аргументов.

map(listvec, ~.y * 2)

Ошибка в .f (.x [[i]], ...): список ... содержит менее 2 элементов

2) Давайте возьмем другой список и теперь добавим listvec1 с listvec2 . Для этого мы можем использовать map2 которого есть два аргумента, поэтому здесь мы .y их .x и .y .

listvec2 <- list(a = 7, b = 8, c = 9)
map2(listvec1,listvec2, ~.x + .y)
#you could actually simplify this as but anyway this is just an example
#map2(listvec1,listvec2, `+`)

#$a
#[1]  8  9 10

#$b
#[1] 12 13 14

#$c
#[1] 11 12 13

В том же самом мы используем .x и .y в imap где .x - элемент, а .y - либо имя списка (если есть), либо индекс.


В посте выше .y ничего не значит, поэтому использовать его как

data_list %>% excel_export("foo.xlsx", table_names = .y)

определенно приведет к ошибке. Вам нужно использовать определенные функции, как описано выше, чтобы использовать .x , .y . Так что если вы хотите использовать каналы для вашей команды, вы должны использовать

data_list %>% excel_export("foo.xlsx", table_names = tab_name)

Есть идеи?

10000