Использование имен списков .f с помощью purrr :: pmap - PullRequest
0 голосов
/ 01 июля 2018

Работает нормально:

pmap_dbl(iris, ~ ..1 + ..2 + ..3 + ..4)

Документация для .l предусматривает A list of lists. ... List names will be used if present.. Это говорит о том, что вы должны иметь возможность работать с именами списка (то есть именами столбцов). Однако:

pmap_dbl(iris, ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width)
Error in .f(Sepal.Length = .l[[c(1L, i)]], Sepal.Width = .l[[c(2L, i)]],  : 
  object 'Sepal.Length' not found

Как имена списков используются на практике?

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Аргумент формулы ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width передается в purrr::as_mapper.

purrr::as_mapper(~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width)
# function (..., .x = ..1, .y = ..2, . = ..1) 
# Sepal.Length + Sepal.Width + Petal.Length + Petal.Width

Вы видите, что для этой функции нет прямого способа узнать, что это за переменные.

Я могу придумать 3 способа обойти это. Я буду использовать пример @ zacdav, так как он более компактен и удобен для чтения, чем ваш:

named_list <- list(one = c(1, 1),
                   two = c(2, 2),
                   three = c(3, 3))

Явное определение

Вы можете явно определить эти переменные, как показано в ответе @ zacdav, он будет работать.


Изучите аргумент точек

Существует способ доступа к именованным аргументам через параметр ... функции, возвращаемой as_mapper.

Аргументы функции именуются, когда имена доступны, как указано в документе другими словами.

Это объясняет, почему pmap(named_list, function(x,y,z) x+y+z) завершится ошибкой:

неиспользованные аргументы (один = .l [[c (1, i)]], два = .l [[c (2, i)]], три = .l [[c (3, i)]] )

См:

pmap(named_list, ~names(list(...)))
# [[1]]
# [1] "one"   "two"   "three"
# 
# [[2]]
# [1] "one"   "two"   "three"

(pmap(unname(named_list), function(x,y,z) x+y+z) с другой стороны будет работать нормально)

Так что это будет работать:

pmap(named_list, ~ with(list(...), one + two + three))
# [[1]]
# [1] 6
# 
# [[2]]
# [1] 6 

Используйте pryr :: f

pryr предлагает удобный ярлык для определений функций с pryr::f:

library(pryr)
f(one + two + three)
# function (one, three, two) 
# one + two + three

pmap(named_list, f(one + two + three))
# [[1]]
# [1] 6
# 
# [[2]]
# [1] 6
# 

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

x <- 1
test <- mean
f(test(x) + lapply(iris,test2))
# function (iris, test2, x) 
# test(x) + lapply(iris, test2)

Так что это не общий подход, и вы должны использовать его только в простых случаях. второй подход, хоть и немного хакерский, будет общим.

Более того, f упорядочивает параметры в алфавитном порядке, это не должно быть проблемой при работе с именованным списком, но будьте осторожны при работе с частично именованными списками.

0 голосов
/ 01 июля 2018
library(purrr)
named_list <- list(one = c(1, 1),
                   two = c(2, 2),
                   three = c(3, 3))

pmap(named_list, function(one, two, three) one + two + three)

Или даже в pmap документации:

# Matching arguments by name
l <- list(a = x, b = y, c = z)
pmap(l, function(c, b, a) a / (b + c))

Это работает, потому что он ожидает увидеть каждый именованный элемент.

pmap_dbl(iris, function(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species) Sepal.Length + Sepal.Width)

Вы также можете использовать ..., кажется:

pmap_dbl(iris, function(Sepal.Length, Sepal.Width, ...) Sepal.Length + Sepal.Width)

в идеале этот пример будет просто использовать rowSums на практике.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...