Несколько функций внутри функции в R - PullRequest
0 голосов
/ 06 марта 2020

Я хотел бы создать функцию с именем g, которая в свою очередь содержит три другие функции f1 и f2. Каждая из двух функций f1, f2 возвращает фрейм данных. Я хотел бы, чтобы функция g возвращала два кадра данных, полученных из f1 и f2. Вот код, который я запускаю:

g <- function(n,a,b,c,d,e) {

    f1 <- function(n,a,b,c,d,e) {
        X <- a*matrix(sample(0:1,n,replace = T),nrow=n,ncol=1)
        Y <- (b*c-d)*matrix(sample(1:10,n,replace = T),nrow=n,ncol=1)
        Z <- (a*e)*matrix(sample(0:12,n,replace = T),nrow=n,ncol=1)
        data1 <- as.data.frame(cbind(X,Y,Z))
        colnames(data1) <- c("X","Y","Z")
        return(data1)
    }
    f1(n,a,b,c,d,e)

    varpredict <- lm(Y ~ 0 + X + Z, data=f1(n,a,b,c,d,e))$fitted.values

    h <- function(){
        olsreg <- lm(Y ~ 0 + X + Z, data=f1(n,a,b,c,d,e))
        P <-  olsreg$residuals^2
        return(P)
    }

    h()

    G <- rep(0,n)
    f2 <- function(n,a,b){
        for (i in 1:n) {
          G[i] <- varpredict[i]-a
        }
        X <- matrix(sample(0:1,n,replace = T),nrow=n,ncol=1)+h()
        Y <- b*matrix(sample(1:10,n,replace = T),nrow=n,ncol=1)
        Z <- (a*b)*matrix(sample(0:12,n,replace = T),nrow=n,ncol=1)-G
        data2 <- as.data.frame(cbind(X,Y,Z))
        colnames(data2) <- c("X","Y","Z")
        return(data2)
    }
    f2(n,a,b)       

    return(list(data1,data2))
}

Чтобы запустить функцию g, я сделал это:

n=100
a=0.3
b=0.5
c=0.3
d=-1.32
e=c*d

my_function <- g(n,a,b,c,d,e)

Но я получил следующее сообщение об ошибке:

Error in g(n, a, b, c, d, e) : object 'data1' not found

Почему я получаю эту ошибку?

1 Ответ

0 голосов
/ 06 марта 2020

Во-первых, когда вы вызываете свои функции f1 и f2, вам нужно где-то хранить их возвращаемое значение.

Во-вторых, неясно, почему вы хотите f1 внутри g: это не Кажется, что оно не имеет общего состояния с g, поэтому его можно определить независимо от g, а не внутри него. Тем не менее, если он когда-либо используется только внутри g, то это в некоторой степени вопрос стиля.

Вот как я бы написал ваш код:

g <- function (n, a, b, c, d, e) {
    f1 <- function (n, a, b, c, d, e) {
        X <- a * matrix(sample(0 : 1, n, replace = TRUE), nrow = n)
        Y <- (b * c - d) * matrix(sample(1 : 10, n, replace = TRUE),nrow = n)
        Z <- (a * e) * matrix(sample(0 : 12, n, replace = TRUE), nrow = n)
        data.frame(X, Y, Z))
    }

    f2 <- function(n, a, b) {
        G <- varpredict - a
        X <- matrix(sample(0 : 1, n, replace = TRUE), nrow = n) + square_res
        Y <- b * matrix(sample(1 : 10, n, replace = TRUE), nrow = n)
        Z <- (a * b) * matrix(sample(0 : 12, n, replace = TRUE), nrow = n) - G
        data.frame(X, Y, Z)
    }

    model <- lm(Y ~ 0 + X + Z, data = f1(n, a, b, c, d, e))
    varpredict <- model$fitted.values
    square_res <- model$residuals ^ 2
    list(f1(n, a, b, c, d, e), f2(n, a, b))
}

Я имею немного исправил код, и я надеюсь, вы согласитесь, что таким образом он более читабелен - он также более эффективен, поскольку позволяет избежать повторного вычисления исходной модели снова и снова. Кроме того, я следовал нескольким простым правилам: используйте постоянный интервал, не используйте произвольные сокращения (T вместо TRUE), используйте соответствующие функции, чтобы избежать избыточного кода (например, создание фреймов данных) , нет ненужного использования return s .

Но, по сути, я до сих пор не знаю, что он делает, так как имена переменных не предоставляют никакой полезной информации. Поэтому самым значительным улучшением читабельности является выбор лучших имен переменных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...