2017-04-20 2 views
1

Je peux exécuter une régression nls en R si je définis explicitement les paramètres ("a" et "b" dans l'exemple ci-dessous). Cependant, comment pourrais-je coder le nls avec un nombre générique de variables/degress plus élevé dans la fonction poly?R - régression non linéaire (nls) et interactions polynomiales (poly)

df <- data.frame(var1 = rnorm(100), var2 = rnorm(100)) 

p <- as.data.frame(poly(df$var2, degree = 2)) 

names(p) <- paste0("poly", names(p)) 

df <- cbind(df, p) 

nls(var1 ~ a*poly1 + b*poly2, data = df, start = list(a = 1, b = 2)) 

Essayer le code, comme cela se fait avec la fonction lm, n'est pas possible:

nls(var1 ~ poly(var2, degree = 2), data = df, start = list(a = 1, b = 2)) #=> Error 
+0

Ceci est fondamentalement la même question posée dans https://stackoverflow.com/questions/3643606/r-polynomial-shortcut-notation-in-nls-formula (qui n'a pas de réponse directe) – Frank

Répondre

1

Vous devez multiplier explicitement le polynôme termes et les coefficients que vous estimez (a et b), comme vous l'avez fait dans le premier exemple. Vous pouvez le faire avec la multiplication de la matrice.

Notez que poly renvoie une matrice, où les lignes alignent avec vos données et les colonnes sont les termes polynomiaux:

> dim(poly(df$var2, degree = 2)) 
[1] 100 2 

Par conséquent, plutôt que de travailler avec a et b séparément, de les combiner dans un vecteur et multiplier la matrice 100 x 2 avec ce 2 x 1 vecteur:

nls(var1 ~ poly(var2, degree = 2) %*% coef, data = df, 
    start = list(coef = c(a = 1, b = 2))) 

cela donne la même réponse que votre exemple de travail.

1

Vous pouvez faire quelque chose comme ceci:

df <- data.frame(var1 = rnorm(100), var2 = rnorm(100)) 

getPoly <- function(df, degree=2) { 
    p <- poly(df$var2, degree = degree) 
    colnames(p) <- paste0("poly", colnames(p)) 
    new_df <- cbind(df, p) 
    formula_str <- paste0("var1~",paste0(paste0(letters[1:degree], "*poly", 1:degree), collapse="+")) 
    return(list(df=new_df, formula_str=formula_str)) 
} 

poly_data <- getPoly(df, 3) 
start_list <- list(a=1,b=2, c=3) 

nls(as.formula(poly_data$formula_str), data = poly_data$df, start = start_list)