2013-07-23 2 views
2

Можно ли написать гибкое выражение функции? Я хочу использовать входные аргументы для управления выражением функции.Как определить гибкое выражение функции в R

Например

input arg -> function 
c(1,1) -> func1 = function(x) x+1 
c(1,3,2) -> func2 = function(x) x^2+3*x+2 
c(6,8,-1) -> func3 = function(x) 6*x^2+8*x-1 
+0

Ваш последний пример должен быть 6x^2 + 8x + 1, я думаю. –

+0

Да, только что скорректированный – user2548246

ответ

2

Вы можете использовать polynom

library(polynom) 
as.polynomial(c(2,3,1)) 
2 + 3*x + x^2 
as.polynomial(c(6,8,1) 
1 + 8*x + 6*x^2 

EDIT вы можете, конечно, принуждать результат функции с помощью the generic as.function.polynomial . better here you can use , as.polylist` к создать много многочленов, заданных списком списков коэффициентов. Например:

lapply(as.polylist(list(c(2,3,1),c(6,8,1),c(6,8,-1))), 
     as.function) 

[[1]] 
function (x) 
{ 
    w <- 0 
    w <- 1 + x * w 
    w <- 3 + x * w 
    w <- 2 + x * w 
    w 
} 
<environment: 0x00000000113bd778> 

[[2]] 
function (x) 
{ 
    w <- 0 
    w <- 1 + x * w 
    w <- 8 + x * w 
    w <- 6 + x * w 
    w 
} 
<environment: 0x0000000011524168> 

[[3]] 
function (x) 
{ 
    w <- 0 
    w <- -1 + x * w 
    w <- 8 + x * w 
    w <- 6 + x * w 
    w 
} 
<environment: 0x0000000011527f28> 
+2

, вероятно, следует упомянуть, что 'as.function' можно использовать для преобразования этого в функцию – eddi

+0

@eddi. Я отредактировал свой ответ, чтобы принудить мой результат к функции. – agstudy

2
makepoly <- function(b) 
{ 
    p <- rev(seq_along(b) - 1) 
    function(x) 
    { 
     xp <- outer(x, p, '^') 
     rowSums(xp * rep(b, each=length(x))) 
    } 
} 

# x^2 + 2x + 3 
f <- makepoly(1:3) 
f(0:4) 
[1] 3 6 11 18 27 
1

Это не понятно, как вообще вы хотите быть от OP. Для частного случая многочленов, вы можете сделать:

f = function(x, coeffs) { 
    sum(outer(x, seq_along(coeffs) - 1, `^`) * coeffs) 
} 

f(2, c(1,2,3)) # 1 + 2*x + 3*x^2, with x = 2 
#[1] 17 
1

Я прочитал это как желание сделать функции, и я думаю, что ответы agstudy/EDDI, вероятно, сделать это, но я думал, пытаясь его с нуля может быть поучительным :

poly.maker <- function(coefs) { func <- function(x){} #empty func in x 
      body(func) <- parse(text= paste(seq_along(coefs),"*x^", 
            (length(coefs)-1):0,collapse="+")) 
      return(func) } 
func2 <- poly.maker(c(1,2,3)) # return a function 
func2(3) # now test it out 
#[1] 18 

Примечание мне нужно поменять порядок, чтобы согласиться с запросом на OP, который я только заметил, после получения различных результатов, чем @dickoa. Это кажется менее неуклюжим:

poly.make2 <- function(coefs) { func <- function(x){} 
     body(func) <- bquote(sum(.(coefs)*x^.((length(coefs)-1):0))) 
     return(func) } 
func <- poly.make2(c(1,2,5)) 
func 
#function (x) 
#sum(c(1, 2, 5) * x^c(2L, 1L, 0L)) 
#<environment: 0x29023d508> 
func(3) 
#[1] 20 
2

Вот моя взять на себя эту задачу

create_poly <- function(coef) 
paste(rev(coef), 
     paste("x", seq_along(coef) - 1, sep = "^"), 
     sep = "*", collapse = " + ") 


make_polyfun <- function(input) { 
    myfun <- paste("function(x)", create_poly(input)) 
    eval(parse(text = myfun)) 
} 

В примере ОП дал нам:

make_polyfun(c(1, 1)) 
## function(x) 1*x^0 + 1*x^1 
## <environment: 0x243a540> 

make_polyfun(c(1, 3, 2)) 
## function(x) 2*x^0 + 3*x^1 + 1*x^2 
## <environment: 0x1bd46e0> 

make_polyfun(c(6, 8, 1)) 
## function(x) 1*x^0 + 8*x^1 + 6*x^2 
## <environment: 0x22a59c0> 
+0

+1; Это на самом деле более чувствительно к вопросу, так как вы заметили, что порядок hte коэффициентов был самым высоким до самого низкого, а я этого не делал. –

+0

@DWin Спасибо, но этот уровень на самом деле не имеет большого значения, просто конвенция. Кстати, приятное использование 'body' – dickoa

+0

Спасибо u dickoa! это то, чего я хочу. извините, мой вопрос не был ясен в 1-м. Мне нужно гибкое выражение функции, которое я могу использовать в других местах, а не в функции. – user2548246

0

Один лайнер:

polymaker2 <- function(coefs) 
{ 
    eval(parse(text=paste0("function(x) sum(x^(",length(coefs)-1,":0) * ",capture.output(dput(coefs)),")"))) 
} 

Векторизованная форма:

polymaker3 <- function(coefs) 
{ 
    eval(parse(text=paste0("function(x) colSums(t(outer(x, ",length(coefs)-1,":0, `^`))*",capture.output(dput(coefs)),")"))) 
} 
+0

Кажется довольно барокко. –

+0

@DWin Согласно Меррину-Вебстеру: «барокко: 1 из, относящееся к или имеющее характеристики стиля художественного выражения, преобладающее, особенно в XVII веке, которое отмечается в целом с помощью сложных форм, смелого орнамента и сопоставление контрастных элементов, часто передающих чувство драмы, движения и напряжения, 2. характеризуется гротескностью, экстравагантностью, сложностью или яркостью, 3. неправильной формы ». Мне нравится первое значение :-) –

+0

Особого внимания заслуживает: '..., capture.output (dput (coefs)) ' –

Смежные вопросы