สตริงอักขระเป็นอาร์กิวเมนต์ฟังก์ชัน r

ฉันกำลังทำงานกับ dplyr และสร้างโค้ดเพื่อคำนวณข้อมูลใหม่ที่ถูกลงจุดด้วย ggplot

ฉันต้องการสร้างฟังก์ชันด้วยโค้ดนี้ ควรใช้ชื่อของคอลัมน์ของกรอบข้อมูลที่ถูกจัดการโดย dplyr อย่างไรก็ตาม การพยายามทำงานกับชื่อคอลัมน์ไม่ได้ผล โปรดพิจารณาตัวอย่างขั้นต่ำด้านล่าง:

df <- data.frame(A = seq(-5, 5, 1), B = seq(0,10,1))

library(dplyr)
foo <- function (x) {
         df %>%
            filter(x < 1)
}

foo(B)

Error in filter_impl(.data, dots(...), environment()) : 
  object 'B' not found 

มีวิธีแก้ไขในการใช้ชื่อของคอลัมน์เป็นอาร์กิวเมนต์ของฟังก์ชันหรือไม่?


person jnshsrs    schedule 23.09.2014    source แหล่งที่มา
comment
คุณช่วยทำให้คำถามของคุณ ทำซ้ำ ได้ไหม ในขณะนี้ คุณกำลังให้ dataframe ที่มีค่าทั้งหมด (สอง) สูงกว่า 1   -  person Jaap    schedule 23.09.2014
comment
ขอบคุณ Jaap สำหรับคำแนะนำของคุณ ฉันแก้ไข df เพื่อให้แน่ใจว่าสามารถทำซ้ำได้   -  person jnshsrs    schedule 23.09.2014
comment
ฉันจำคำถามที่คล้ายกันซึ่งตอบโดย @Richard Scriven ฉันคิดว่าคุณต้องเขียนบางอย่างเช่น foo <- function(x,...)filter(x,...) ฉันมีสิ่งต่อไปนี้ตอนนี้ ไม่แน่ใจว่าฉันเขียนสิ่งที่ถูกต้องหรือไม่ แต่ผลลัพธ์ดูเหมือนจะถูกต้อง.foo <- function (x,...) filter(x,...);foo(df, B < 1)   -  person jazzurro    schedule 23.09.2014
comment
@jazzurro น่าเสียดายที่ฉันไม่สามารถทำซ้ำคำแนะนำของคุณได้ บางทีคุณอาจมีส่วนสนับสนุนตัวอย่างที่ทำซ้ำได้   -  person jnshsrs    schedule 23.09.2014
comment
@jnshsrs ฉันใช้ df ของคุณและรันโค้ด R ส่งคืนแถวแรก คุณสามารถรันโค้ดด้วย df บนเครื่องของคุณได้ไหม?   -  person jazzurro    schedule 23.09.2014
comment
@jazzurro โอเค ฉันสามารถรันโค้ดได้ ฉันพยายามใช้สิ่งนี้ในฟังก์ชันของฉันและให้ข้อเสนอแนะเกี่ยวกับผลลัพธ์ ขอบคุณจนถึงตอนนี้!   -  person jnshsrs    schedule 23.09.2014
comment
@jnshsrs ตกลง ฉันดีใจที่ได้ยินเช่นนั้น ฉันจะแสดงความคิดเห็นของฉันเป็นคำตอบแล้ว   -  person jazzurro    schedule 23.09.2014


คำตอบ (2)


หากคุณต้องการสร้างฟังก์ชันที่ยอมรับสตริง "B" เป็นอาร์กิวเมนต์ (เช่นเดียวกับในชื่อคำถามของคุณ)

foo_string <- function (x) {
         eval(substitute(df %>% filter(xx < 1),list(xx=as.name(x))))
}
foo_string("B")

หากคุณต้องการสร้างฟังก์ชันที่ยอมรับการจับ B เป็นอาร์กิวเมนต์ (เช่นเดียวกับใน dplyr)

foo_nse <- function (x) {
         # capture the argument without evaluating it
         x <- substitute(x)
         eval(substitute(df %>% filter(xx < 1),list(xx=x)))
}
foo_nse(B)

คุณสามารถดูข้อมูลเพิ่มเติมได้ใน Advanced R

แก้ไข

dplyr ทำให้สิ่งต่างๆ ง่ายขึ้นในเวอร์ชัน 0.3 ฟังก์ชันที่มีส่วนต่อท้าย "_" ยอมรับสตริงหรือนิพจน์เป็นอาร์กิวเมนต์

 foo_string <- function (x) {
             # construct the string
             string <- paste(x,"< 1")
             # use filter_ instead of filter
             df %>% filter_(string)
    }
foo_string("B")
 foo_nse <- function (x) {
             # capture the argument without evaluating it
             x <- substitute(x)
             # construct the expression
             expression <- lazyeval::interp(quote(xx < 1), xx = x)
             # use filter_ instead of filter
             df %>% filter_(expression)
    }
foo_nse(B)

คุณสามารถดูข้อมูลเพิ่มเติมได้ในบทความสั้นนี้

person Matthew    schedule 23.09.2014
comment
ขอบคุณสำหรับข้อมูลเพิ่มเติมนี้ สิ่งนี้มีประโยชน์มากสำหรับฉัน - person jnshsrs; 24.09.2014

ฉันจำคำถามที่คล้ายกันซึ่งตอบโดย @Richard Scriven ฉันคิดว่าคุณต้องเขียนอะไรแบบนี้

foo <- function(x,...)filter(x,...) 

สิ่งที่ @Richard Scriven พูดถึงคือคุณต้องใช้ ... ที่นี่ หากคุณพิมพ์ ?dplyr คุณจะพบสิ่งนี้: filter(.data, ...) ฉันคิดว่าคุณแทนที่ .data ด้วย x หรืออะไรก็ตาม หากคุณต้องการเลือกแถวที่มีค่าน้อยกว่า 1 ใน B ใน df ของคุณ มันจะเป็นเช่นนี้

foo <- function (x,...) filter(x,...)
foo(df, B < 1)
person jazzurro    schedule 23.09.2014
comment
ฉันคงจะแก่แล้ว ฉันไม่มีความทรงจำเกี่ยวกับเรื่องนี้ แต่ +1 เพราะมันได้ผล! - person Rich Scriven; 23.09.2014
comment
@RichardScriven ฉันผิดได้ แต่ฉันคิดว่าเป็นคุณที่ตอบคำถามที่คล้ายกันโดยใช้ select() นั่นคือแรงบันดาลใจของฉัน โค้ดด้านบนใช้งานได้ แต่ฉันรู้สึกประหลาดใจเมื่อเห็นสิ่งนั้น - person jazzurro; 24.09.2014