2016-09-01 6 views
2

Я новичок в R, и я хочу улучшить следующий скрипт с помощью функции *apply (я прочитал около apply, но я не смог ее использовать). Я хочу использовать функцию lm для нескольких независимых переменных (которые являются столбцами в кадре данных). Я использовалУстановка линейной модели с несколькими LHS

for (i in (1:3) { 
    assign(paste0('lm.',names(data[i])), lm(formula=formula(i),data=data)) 
    } 

Formula(i) определяется как

formula=function(x) 
{ 
    as.formula (paste(names(data[x]),'~', paste0(names(data[-1:-3]), collapse = '+')), env=parent.frame()) 
} 

Спасибо.

ответ

5

Если я не получаю, что вы неправы, вы работаете с набором данных, как это:

set.seed(0) 
dat <- data.frame(y1 = rnorm(30), y2 = rnorm(30), y3 = rnorm(30), 
        x1 = rnorm(30), x2 = rnorm(30), x3 = rnorm(30)) 

x1, x2 и являются ковариат, в то время как y1, y2 и y3 являются три независимые реакции. Вы пытаетесь соответствовать три линейные модели:

y1 ~ x1 + x2 + x3 
y2 ~ x1 + x2 + x3 
y3 ~ x1 + x2 + x3 

В настоящее время вы используете петлю через y1, y2, y3, приспосабливая одну модель за единицу времени. И вы надеетесь ускорить процесс, заменив цикл for, скажем, lapply.

Я хотел бы указать, что вы на неправильном пути.lm() - дорогая операция. Пока ваш набор данных невелик, затраты на цикл for незначительны. Замена петли for с lapply не дает прироста производительности.

Поскольку у вас есть те же самые RHS для всех трех моделей, модельная матрица одинакова для трех моделей. Поэтому QR-факторизация для всех моделей нужно делать только один раз. lm позволяет это, и вы можете использовать:

fit <- lm(cbind(y1, y2, y3) ~ x1 + x2 + x3, data = dat) 
#Coefficients: 
#    y1   y2   y3  
#(Intercept) -0.081155 0.042049 0.007261 
#x1   -0.037556 0.181407 -0.070109 
#x2   -0.334067 0.223742 0.015100 
#x3   0.057861 -0.075975 -0.099762 

Если вы проверяете str(fit), вы увидите, что это не список из трех линейных моделей; вместо этого это единственная линейная модель с единственным объективом $qr, но с несколькими LHS. Таким образом, $coefficients, $residuals и $fitted.values являются матрицами.

Если у вас есть гораздо больше ковариат, вы можете избежать ввода или вставки формулы с помощью .:

fit <- lm(cbind(y1, y2, y3) ~ ., data = dat) 
#Coefficients: 
#    y1   y2   y3  
#(Intercept) -0.081155 0.042049 0.007261 
#x1   -0.037556 0.181407 -0.070109 
#x2   -0.334067 0.223742 0.015100 
#x3   0.057861 -0.075975 -0.099762 

Внимание: Не пишите:

y1 + y2 + y3 ~ x1 + x2 + x3 

Это будет обработать y = y1 + y2 + y3 как единый ответ. Используйте cbind().


Последующая деятельность:

Спасибо за ваш ответ. Меня интересует обобщение.Позвольте мне быть более конкретным. У меня есть фрейм данных df, где первые n столбцы являются независимыми переменными (y1,y2,y3,....) и следующие m столбцы являются зависимыми переменными (x1+x2+x3+....). Для n=3 и m=3 это в случае с fit <- lm(cbind(y1, y2, y3) ~ ., data = dat)). Но как это можно сделать автоматически, используя структуру df. Я имею в виду что-то вроде (for i in (1:n)) fit <- lm(cbind(df[something] ~ df[something], data = dat)). Это «что-то» я создал с paste и paste0. Спасибо.

Вы все еще можете создать модельную формулу paste и paste0:

paste0("cbind(", paste(names(df)[1:n], collapse = ", "), ")", " ~ .") 

Например, используя iris набор данных:

paste0("cbind(", paste(names(iris)[1:2], collapse = ", "), ")", " ~ .") 
# "cbind(Sepal.Length, Sepal.Width) ~ ." 

Вы можете передать эту строку формулу lm как lm будет автоматически принуждать его к классу формул.

+0

Здравствуйте, и благодарю вас за ответ. Меня интересует обобщение. Позвольте мне быть более конкретным. У меня есть кадр данных (df), где первые n столбцов являются независимыми переменными (y1, y2, y3, ....), а следующие m столбцов являются зависимыми переменными (x1 + x2 + x3 + ....). При n = 3 и m = 3 это имеет место с fit <- lm (cbind (y1, y2, y3) ~., Data = dat)). Но как это можно сделать автоматически, используя структуру df? Я имею в виду что-то вроде (для i in (1: n)) fit <- lm (cbind (df [something] ~., Data = dat)). Должен ли я разделить df - для (для i в (1: n)) y (i) <- df [i]? Или альтернатива для. Спасибо. –

+0

Да, это прекрасно. Спасибо! –

+0

Конечно, но как проголосовать? –

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