2017-08-07 26 views
0

下面這段代碼按預期工作:purrr :: PMAP與用戶定義的函數和命名列表

library(tidyverse) 
tib <- tibble(x = c(1,2), y = c(2,4), z = c(3,6)) 
tib %>% pmap(c) 
#[[1]] 
#x y z 
#1 2 3 
# 
#[[2]] 
#x y z 
#2 4 6 

但是如果我定義函數

my_c_1 <- function(u, v, w) c(u, v, w) 

我得到一個錯誤:

tib %>% pmap(my_c_1) 
#Error in .f(x = .l[[c(1L, i)]], y = .l[[c(2L, i)]], z = .l[[c(3L, i)]], : 
# unused arguments (x = .l[[c(1, i)]], y = .l[[c(2, i)]], z = .l[[c(3, i)]]) 

等效,爲基本載體功能命名列表一切運作良好:

lili_1 <- list(x = list(1,2), y = list(2,4), z = list(3,6)) 
pmap(lili_1, c) 
#[[1]] 
#x y z 
#1 2 3 
# 
#[[2]] 
#x y z 
#2 4 6 

並與用戶定義的函數,我得到了同樣的錯誤:

pmap(lili_1, my_c_1) 
#Error in .f(x = .l[[c(1L, i)]], y = .l[[c(2L, i)]], z = .l[[c(3L, i)]], : 
#unused arguments (x = .l[[c(1, i)]], y = .l[[c(2, i)]], z = .l[[c(3, i)]]) 

然而,對於用戶定義函數未命名的列表,它的工作原理:

lili_2 <- list(list(1,2), list(2,4), list(3,6)) 
pmap(lili_2, my_c_1) 
#[[1]] 
#[1] 1 2 3 
# 
#[[2]] 
#[1] 2 4 6 

我不太明白爲什麼事情與命名列表和用戶定義的函數有衝突。任何見解?

BTW,我發現了一個暫時的解決辦法定義:

my_c_2 <- function(...) c(...) 

然後一切運作良好,甚至有一個名爲列表...這讓我更加疑惑。
這是一個最小可重現的例子的精神。在我目前的工作代碼中,我希望能夠使用我的更一般定義的函數將tibbles管道映射到pmap,而無需使用變量的...變通辦法。

+0

忘了提及我正在使用R版本3.4.1與purrr_0.2.3(在macOS Sierra 10.12.6上)。 – Habert

回答

0

你的函數my_c_1有參數uvw但你通過與名xyz列表。如果你不想要一個沒有命名參數的函數(...,比如基地的c),你應該確保你的通話中的名字相符。

+0

謝謝!如果我定義'my_c_1 < - 函數(x,y,z)c(x,y,z)',它確實有效,但這很不方便。我可能想用pmap和許多不同的小節來使用這個函數,這些小節不一定要命名爲'x','y'和'z'。不應該在函數定義中的變量的名稱獨立於輸入的名稱。 map2沒有這樣的問題,例如'map2(lili_1 [[1]],lili_1 [[2]],my_c_3)'與'my_c_3 < - function(u,v)c(u,v)'一起工作。 – Habert

+0

它與map2「起作用」,因爲lili_1 [[1]]'沒有名稱,在這種情況下,它會採用位置匹配。 R中的一個通用特性和約定是命名調用參數必須與函數調用中的命名參數相匹配。如果你只想依靠位置匹配,你必須去掉這些名字,或者有一個沒有命名參數的函數。 – baptiste

+0

感謝您的解釋! 'pmap(unname(lili_1),my_c_1)'很好。這是一個滿意的解決方案。 – Habert

相關問題