string karakter sebagai argumen fungsi r

Saya bekerja dengan dplyr dan membuat kode untuk menghitung data baru yang diplot dengan ggplot.

Saya ingin membuat fungsi dengan kode ini. Ini harus mengambil nama kolom bingkai data yang dimanipulasi oleh dplyr. Namun, mencoba bekerja dengan nama kolom tidak berhasil. Silakan pertimbangkan contoh minimal di bawah ini:

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 

Apakah ada solusi untuk menggunakan nama kolom sebagai argumen fungsi?


person jnshsrs    schedule 23.09.2014    source sumber
comment
Bisakah Anda membuat pertanyaan Anda dapat direproduksi? Saat ini Anda memberikan kerangka data dengan semua (dua) nilai di atas 1.   -  person Jaap    schedule 23.09.2014
comment
Terima kasih Jaap atas saran Anda, saya mengedit df untuk memastikan reproduktifitas   -  person jnshsrs    schedule 23.09.2014
comment
Saya ingat pertanyaan serupa yang dijawab oleh @Richard Scriven. Saya pikir Anda perlu menulis sesuatu seperti foo <- function(x,...)filter(x,...) Saya punya yang berikut ini sekarang. Tidak yakin apakah saya menulis sesuatu dengan benar. Tapi hasilnya sepertinya benar.foo <- function (x,...) filter(x,...);foo(df, B < 1)   -  person jazzurro    schedule 23.09.2014
comment
@jazzurro, sayangnya saya tidak dapat mereproduksi saran Anda. Mungkin Anda dapat memberikan contoh yang dapat direproduksi.   -  person jnshsrs    schedule 23.09.2014
comment
@jnshsrs Saya menggunakan df Anda dan menjalankan kodenya. R mengembalikan baris pertama. Bisakah Anda menjalankan kode dengan df di mesin Anda?   -  person jazzurro    schedule 23.09.2014
comment
@jazzurro, oke, saya bisa menjalankan kodenya. Saya mencoba menerapkan ini dalam fungsi saya dan memberikan umpan balik mengenai hasilnya. Terima kasih sejauh ini!   -  person jnshsrs    schedule 23.09.2014
comment
@jnshsrs Oke, saya senang mendengarnya. Saya akan meninggalkan komentar saya sebagai jawaban.   -  person jazzurro    schedule 23.09.2014


Jawaban (2)


Jika Anda ingin membuat fungsi yang menerima string "B" sebagai argumen (seperti pada judul pertanyaan Anda)

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

Jika Anda ingin membuat fungsi yang menerima tangkapan B sebagai argumen (seperti pada 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)

Anda dapat menemukan informasi lebih lanjut di R Lanjutan

Sunting

dplyr membuat segalanya lebih mudah di versi 0.3. Fungsi dengan akhiran "_" menerima string atau ekspresi sebagai argumen

 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)

Anda dapat menemukan informasi selengkapnya di sketsa ini

person Matthew    schedule 23.09.2014
comment
Terima kasih atas informasi tambahan ini. Ini sangat berguna bagi saya. - person jnshsrs; 24.09.2014

Saya ingat pertanyaan serupa yang dijawab oleh @Richard Scriven. Saya pikir Anda perlu menulis sesuatu seperti ini.

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

Apa yang disebutkan @Richard Scriven adalah Anda perlu menggunakan ... di sini. Jika Anda mengetik ?dplyr, Anda akan menemukan ini: filter(.data, ...) Saya rasa Anda mengganti .data dengan x atau apa pun. Jika Anda ingin mengambil baris yang nilainya lebih kecil dari 1 di B di df Anda, akan menjadi seperti ini.

foo <- function (x,...) filter(x,...)
foo(df, B < 1)
person jazzurro    schedule 23.09.2014
comment
Saya pasti semakin tua. Saya tidak ingat hal ini. Tapi +1, karena berhasil! - person Rich Scriven; 23.09.2014
comment
@RichardScriven Saya bisa saja salah. Tapi, menurut saya Andalah yang menjawab pertanyaan serupa menggunakan select(). Itu adalah inspirasi saya. Kode di atas berfungsi, tetapi saya terkejut saat melihatnya. - person jazzurro; 24.09.2014