R: ใช้ตัวดำเนินการท่อ magrittr ในแพ็คเกจที่เขียนขึ้นเอง


104

ฉันต้องการใช้ตัวดำเนินการไปป์ที่%>%แนะนำในmagrittrแพ็คเกจในแพ็คเกจที่ฉันเขียนเองเพื่อเชื่อมโยงการdplyrแปลงข้อมูล magrittrแสดงอยู่ImportในDESCRIPTIONไฟล์ หลังจากโหลดแพ็คเกจของฉันเองและทดสอบฟังก์ชันที่ใช้ตัวดำเนินการไปป์ฉันได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:

ข้อผิดพลาดในชื่อฟังก์ชัน (พารามิเตอร์: ไม่พบฟังก์ชัน "%>%"

การเปลี่ยน%>%ไปใช้magrittr::%>%ในซอร์สโค้ดของฟังก์ชันไม่ได้ช่วยอย่างใดอย่างหนึ่งเนื่องจากไม่สามารถสร้างแพ็คเกจได้อีกต่อไป


6
ฉันขอแนะนำให้ต่อต้านตัวดำเนินการท่อภายในฟังก์ชันภายในบรรจุภัณฑ์ ทำให้การดีบักยากขึ้นมาก (call stack ลึกลงไปอย่างบ้าคลั่งกับท่อ) สำหรับแพ็คเกจฉันเพิ่งเขียนทับตัวแปรชั่วคราวซึ่งทำให้การทดสอบง่ายขึ้นมาก (คิดว่า: R บอกคุณว่าเกิดข้อผิดพลาดอะไร) ท่อนี้ใช้ได้ดีสำหรับการใช้งานแบบโต้ตอบ แต่สำหรับการเขียนโปรแกรมอาจเป็นภาระ

คำตอบ:


104

มันควรจะได้ทำงานได้อย่างถูกต้องถ้าคุณได้ระบุไว้ในmagrittr Dependsอย่างไรก็ตามไม่แนะนำให้ทำเช่นนี้ แต่คุณออกจากmagrittrในImportsและเพิ่มบรรทัดต่อไปนี้NAMESPACE:

importFrom(magrittr,"%>%")

ผมขอแนะนำให้อ่านส่วนขยาย R เขียน คำถามของคุณครอบคลุมในย่อหน้า 1.1.3 และ 1.5.1


1
@alexanderketh ในกรณีนี้คุณควรกดเครื่องหมายถูกสีเขียวถัดจากคำตอบเพื่อทำเครื่องหมายว่ายอมรับ ยินดีต้อนรับสู่ SO!
tonytonov

55
หากคุณกำลังใช้roxygen2คุณสามารถเพิ่ม#' importFrom magrittr "%>%"จะมี NAMESPACE roxygenize()ประชากรโดยอัตโนมัติในระหว่าง
Roman Luštrik

38
@ RomanLuštrikเพิ่งหายไป @ น่าจะ#' @importFrom magrittr "%>%"
Roah

13
โปรดทราบว่าสิ่งนี้จะอนุญาตให้คุณใช้%>%ภายในแพ็กเกจของคุณเท่านั้น หาก API ของคุณต้องการให้ผู้ใช้ฟังก์ชั่นการใช้โซ่พวกเขาจะยังคงมีการโหลดอย่างชัดเจน%>% magrittrวิธีหนึ่งในการแก้ปัญหานี้คือการส่งออกฟังก์ชันใหม่ นี่คือตัวอย่างวิธีการทำ
รามนาถ

และนี่ก็เป็นสิ่งที่แพคเกจ usethis ไม่เป็นที่กล่าวถึงที่นี่
jiggunjer

33

วิธีแก้ปัญหาเพิ่มเติมหนึ่งวิธี - ใช้roxygenแพ็คเกจ มันใช้งานเป็นส่วนหนึ่งของdevtoolsแพ็คเกจ เมื่อdevtoolsติดตั้งแล้วการโทรdevtools::document()จะอัปเดตNAMESPACEให้คุณ นอกจากนี้ยังสร้างไฟล์. RD อัตโนมัติพร้อมเอกสารประกอบซึ่งสะดวก

สิ่งที่คุณทำคือเพิ่มข้อคิดเห็นพิเศษในรูปแบบ#' @import packagenameลงในไฟล์เพื่อนำเข้าฟังก์ชันทั้งหมดจากแพ็คเกจนั้นหรือ#' @importFrom packagename functionnameเพื่อนำเข้าฟังก์ชัน คุณสามารถมีความคิดเห็นเหล่านี้ได้มากเท่าที่คุณต้องการในไฟล์ของคุณดังนั้นคุณสามารถตั้งค่าความคิดเห็นเหล่านี้ไว้ที่ด้านบนของแต่ละไฟล์หรือกับแต่ละฟังก์ชันที่ต้องการฟังก์ชันภายนอก

จากนั้นคุณจะเรียกใช้devtools::document()และจะแยกวิเคราะห์โค้ดของคุณเพื่อค้นหาความคิดเห็นเหล่านั้นจากนั้นจะสร้างNAMESPACEไฟล์ที่เหมาะสมสำหรับคุณ ง่าย.


1
เมื่อฉันทำสิ่งนี้ความคิดเห็นของออกซิเจนต่อไปนี้ที่เกี่ยวข้องกับไฟล์วิธีใช้สำหรับฟังก์ชันแรกในสคริปต์ R จะทำให้สับสน ฉันจะแยกความคิดเห็นเกี่ยวกับออกซิเจนทั่วโลกออกจากไฟล์ความช่วยเหลือได้อย่างไร
jzadra

2
ฉันมักจะใส่ความคิดเห็นในการนำเข้าพร้อมกับแต่ละฟังก์ชันทีละรายการ ด้วยวิธีนี้หากฟังก์ชันอื่น ๆ ในไฟล์เปลี่ยนไปการนำเข้าของคุณจะยังคงถูกต้อง ดังนั้นจึงไม่มีคำจำกัดความทั่วโลก
Mike Stanley

33

ตอนนี้มีวิธีที่ง่ายกว่าในการรองรับท่อในหีบห่อของคุณ แพคเกจที่ยอดเยี่ยมที่มีฟังก์ชั่นusethis use_pipe()คุณเรียกใช้ฟังก์ชันนั้นเพียงครั้งเดียวและจัดการทุกอย่าง นี่คือวิธีuse_pipe()อธิบายฟังก์ชันในusethisเอกสารประกอบ:

จำเป็นต้องตั้งค่าเพื่อใช้ไปป์ magrittr ภายในแพ็คเกจของคุณหรือไม่และเพื่อส่งออกใหม่สำหรับผู้ใช้แพ็กเกจของคุณ:

เพิ่ม magrittr ใน "นำเข้า" ใน DESCRIPTION

สร้าง R / utils-pipe.R ด้วยเทมเพลต roxygen ที่จำเป็น


คุณเพิ่มบรรทัดuse_pipe()ลงในโค้ดที่ใช้สร้างแพ็คเกจหรือไม่ ตัวอย่างเช่นฉันเรียกใช้: usethis::use_description(usethis_description); usethis::use_build_ignore(directories); usethis::use_build_ignore(paste0(pkg_name, ".Rproj")); if (file.exists(file.path(pkg_path, "NAMESPACE"))) { file.remove(file.path(pkg_path, "NAMESPACE")) }; devtools::document(pkg_path); devtools::check(pkg_path); devtools::load_all(pkg_path); devtools::install(pkg_path). ฉันจะเพิ่มuse_pipe()ที่จุดเริ่มต้นหรือไม่
Josh

1
@ Josh คุณใช้usethisฟังก์ชันครั้งเดียวเมื่อคุณกำลังพัฒนาแพ็คเกจ ฟังก์ชั่นเหล่านั้นจะเพิ่มส่วนที่จำเป็นในคำแนะนำการสร้างและอื่น ๆ
Andrew Brēza

18

สมมติว่าคุณกำลังใช้ RStudio devtoolsแพ็คเกจของ Hadley และอยู่magrittrในส่วนการนำเข้าของDESCRIPTIONไฟล์นี่คือขั้นตอนที่ฉันใช้เพื่อให้%>%ทำงานในฟังก์ชันแพ็กเกจของฉัน

ขั้นแรกเขียนฟังก์ชันfoo.R:

#' Convert \code{data.frame} to \code{list}.
#' 
#' @importFrom magrittr %>%
#' @name %>%
#' @rdname pipe
#' @export
#' @param x A \code{data.frame} object.
#' @examples
#' my_result <- foo(iris)
#'
foo <- function(x) {
    x %>%
        as.list()
}

devtools::document()ประการที่สองการทำงาน

ประการที่สามเรียกใช้ devtools::load_all()ประการที่สามการทำงาน

ไฟล์เช่นนี้จะถูกสร้างขึ้นในR/ไดเร็กทอรีของคุณและฟังก์ชันของคุณจะทำงานได้ตามที่คาดไว้


7
จุดประสงค์ของ@name %>%ที่นี่คืออะไร?
JelenaČuklina
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.