2015-12-09 24 views
8

Tôi muốn viết hàm R có chức năng toán học trong x và trả về một hàm mới trong x làm đầu ra. Ví dụ:Truyền chức năng làm chức năng nhập và trả về

Các đầu vào phải được thông qua tại như một hàm toán học (hoặc liên quan) trong x:

g <- x^2 + 9*x + log(x) 

Và kết quả đầu ra nên là:

function(x) (exp(g)) 

tức là tôi muốn trở lại biểu thức hàm mũ biểu tượng của hàm ban đầu trong x tức là exp(x^2 + 9*x + log(x)) trong ví dụ minh họa này

Vì vậy, lý tưởng nó sẽ trả lại đối tượng chức năng:

function(x) (exp(x^2 + 9*x + log(x))) 

tôi đã cố gắng như sau:

test <- function(g){ 
h <- function(x){exp(g)} 
return(h) 
} 
m <- test(x^2 + 9*x + log(x)) 
m(10) 

Vì vậy m (10) sẽ trả về:

exp(10^2 + 9*10 + log(10)) 

đó là exp (192,3026) trong trường hợp này.

Có ai có thể cho biết cách thực hiện việc này không?

+0

này cũng tương tự như sự khác biệt mang tính biểu tượng, đúng không? 'deriv (expr, ...)' – jogo

+0

Không - không có sự phân biệt nào ở đây. Chỉ muốn tạo/trả về một đối tượng hàm mới (tức là exp (10^2 + 9 * 10 + log (10))) từ hàm được truyền vào như một đầu vào (tức là x^2 + 9 * x + log (x)). – user4687531

+0

vì lý do đó tôi đã viết "tương tự".Tôi biết rằng bạn muốn một sự biến đổi của biểu thức biểu tượng. – jogo

Trả lời

3

chỉnh sửa - cho các chức năng trong câu hỏi

f <- function(...) { 
    l <- eval(substitute(alist(x = x, ...))) 
    l[[2]] <- substitute(exp(X), list(X = l[[2]])) 
    as.function(`names<-`(l, l[sapply(l, is.symbol)])) 
} 

g <- f(x^2 + 2*x + 5) 
# function (x = x) 
# exp(x^2 + 2 * x + 5) 

g(1) 
# [1] 2980.958 

Dưới đây là một cách khác cho một trường hợp chung:

f <- function(...) { 
    l <- eval(substitute(alist(...))) 
    as.function(`names<-`(l, l[sapply(l, is.symbol)])) 
} 

g <- f(x, x^2 + 9*x + log(x)) 

# function (x = x) 
# x^2 + 9 * x + log(x) 

g(10) 
# [1] 192.3026 

Phiên bản này cũng sẽ làm việc cho bất kỳ số lượng biến, chỉ cần xác định họ tiếp theo là chức năng:

g <- f(x, y, z, x + 2 * y + z ** 3) 

# function (x = x, y = y, z = z) 
# x + 2 * y + z^3 

g(1, 2, 0) 
# [1] 5 

Có thể có một cách tốt hơn để thêm ... chức năng, nhưng đây là cách bạn có thể làm điều đó

f <- function(..., use_dots = FALSE) { 
    l <- eval(substitute(alist(...))) 
    if (use_dots) 
    l <- c(head(l, -1), list('...' = as.symbol('...')), tail(l, 1)) 
    as.function(`names<-`(l, l[sapply(l, is.symbol)])) 
} 

Vì vậy, bây giờ bạn không phải đặt tên cho tất cả các biến/đối số

g <- f(x, y, plot(x, y, ...), use_dots = TRUE) 
g(1:5, 1:5, main = 'main title', pch = 16, col = 3, cex = 3, xpd = NA) 

enter image description here

+0

Cảm ơn. Tôi đã thử những điều sau đây cho ứng dụng của tôi nhưng không hoàn toàn làm việc: f <- function (...) { l <- eval (thay thế (alist (...))) as.function ('name <-' (l, l [sapply (l, is.symbol)])) } test2 <- function (g) { # Tạo hàm h (x) là hàm # của đầu vào g (x) chức năng thông qua tại như một chuỗi h <- f (x, exp (g)) return (h) } y <- test2 (x^2 + 2 * x) y (10) y_prime < - D (body (y), 'x') y_prime – user4687531

+0

Tôi muốn trả về hàm exp (hàm) và sau đó lấy đạo hàm của nó . Bạn có thể vui lòng hỗ trợ vì phương pháp này có vẻ ngắn gọn và hữu ích không nếu tôi có thể làm cho nó hoạt động – user4687531

+0

@ user4687531 thay đổi g thành x và nó sẽ hoạt động. các biến cần phải khớp, nếu không hàm không biết phải sử dụng gì, ví dụ 'test2 <- function (x) f (x, exp (x))' – rawr

7

Dưới đây là một cách tiếp cận:

test <- function(e) { 
    ee <- substitute(e) 
    eee <- substitute(exp(X), list(X=ee)) 
    f <- function(x) {} 
    body(f) <- eee 
    environment(f) <- parent.frame() 
    f 
} 

## Check that it works 
m <- test(x^2 + 9*x + log(x)) 
m 
# function (x) 
# exp(x^2 + 9 * x + log(x)) 
m(1) 
# [1] 22026.47 
m(1) == exp(10) 
# [1] TRUE 
+1

Để biết thêm về chức năng xây dựng theo lập trình, [xem tại đây] (http://stackoverflow.com/questions/12982528/how-to-create-an-r-function-programmatically) –

+1

Vui lòng xem xét chỉnh sửa bài đăng của bạn để thêm giải thích thêm về mã của bạn làm gì và tại sao nó sẽ giải quyết vấn đề. Một câu trả lời mà hầu hết chỉ chứa mã (ngay cả khi nó hoạt động) thường không giúp OP hiểu được vấn đề của họ. – SuperBiasedMan

+1

@SuperBiasedMan - Vui lòng xem xét chỉ cụ thể đến nội dung của mã mà bạn không hiểu và muốn được trợ giúp. Hoặc bạn có biết OP, và biết rằng câu trả lời chỉ chứa mã (sử dụng các chức năng phổ biến và được ghi chép đầy đủ) sẽ không giúp ích cho họ? (Trong trường hợp đó, xấu của tôi - bạn có thể cho tôi biết một số gợi ý về trải nghiệm của họ với tư cách là người dùng R hay không và có thể yêu cầu họ liên hệ với tôi bằng các câu hỏi của họ?) –

10

Bạn có thể sử dụng gói chức năng:

library(functional) 
fun <- Compose(function(x) x^2 + 9*x + log(x), exp) 
fun(1) 
#[1] 22026.47 
+0

Vui lòng xem xét chỉnh sửa bài đăng của bạn để thêm giải thích thêm về mã của bạn và tại sao nó sẽ giải quyết vấn đề. Một câu trả lời mà hầu hết chỉ chứa mã (ngay cả khi nó hoạt động) thường không giúp OP hiểu được vấn đề của họ. – SuperBiasedMan

+8

@SuperBiasedMan Vui lòng ngừng đăng những nhận xét vô ích này. – Roland

+5

@SuperBiasedMan Vui lòng xem xét sử dụng hạn chế nhiều hơn với đánh giá tự động nhận xét. Mặc dù đôi khi các nhận xét chung có thể là một bổ sung mang tính xây dựng cho một Giải Đáp, các nhận xét không nhận ra sự khác biệt giữa mã yêu cầu giải thích và mã dài mà thường không giúp cải thiện nội dung trên StackOverflow. ;) – joran

Các vấn đề liên quan