R newbie having issues with lm function - r

I have the following code to get the famafrench regression of a set of data:
#Regression
ff_reg = lm(e25 ~ rmrf+smb+hml, data=dat);
However, I keep getting the error "invalid type (list) for variable e25".
e25 was defined earlier in the program as a set of data obtained from subtracting 'rf' from a matrix made up of 25 columns:
e25 = (dat[,7:31]) - dat$rf;
(where dat is an CSV file read in to R and rf is one of the columns within that file)
Why is this error coming up and how can I resolve it?
On advice, here is the full code that I am running...
dat = read.csv("ff2014.csv", as.is=TRUE);
##excess portfolio returns
e25 = (dat[,7:31]) - dat$rf;
#print(e25);
#Regression
ff_reg = lm(e25 ~ rmrf+smb+hml, data=dat);
print(summary(ffreg));

From help("lm"):
If response is a matrix a linear model is fitted separately by least-squares to each column of the matrix.
So, if that's what you intend to do, you need to make your data.frame a matrix before you call lm:
e25 <- as.matrix(e25)

Related

Using a For Loop to Run Multiple Response Variables through a Train function to create multiple seperate models in R

I am trying to create a for loop to index thorugh each individual response variable I have and train a model using the train() funciton within the Caret Package. I have about 30 response variable and 43 predictor variables. I can train each model individually but I would like to automate the process and have a for loop run through a model (I would like to eventually upscale to multiple models if possible, i.e. lm, rf, cubist, etc.). I then want to save each model to a dataframe along with R-squared values and RMSE values. The individual models that I currenlty have that will run for me goes as follows, with column 11 being the response variable and column 35-68 being predictor variables.
data_Mg <- subset(data_3, !is.na(Mg))
mg.lm <- train(Mg~., data=data_Mg[,c(11,35:68)], method="lm", trControl=control)
mg.cubist <- train(Mg~., data=data_Mg[,c(11,35:68)], method="cubist", trControl=control)
mg.rf <- train(Mg~., data=data_Mg[,c(11,35:68)], method="rf", trControl=control, na.action = na.roughfix)
max(mg.lm$results$Rsquared)
min(mg.lm$results$RMSE)
max(mg.cubist$results$Rsquared)
min(mg.cubist$results$RMSE)
max(mg.rf$results$Rsquared) #Highest R squared
min(mg.rf$results$RMSE)
This gives me 3 models with everything the relevant information that I need. Now for the for loop. I've only tried the lm model so far for this.
bucket <- list()
for(i in 1:ncol(data_4)) { # for-loop response variables, need to end it at response variables, rn will run through all variables
data_y<-subset(data_4, !is.na(i))#get rid of NA's in the "i" column
predictors_i <- colnames(data_4)[i] # Create vector of predictor names
predictors_1.1 <- noquote(predictors_i)
i.lm <- train(predictors_1.1~., data=data_4[,c(i,35:68)], method="lm", trControl=control)
bucket <- i.lm
#mod_summaries[[i - 1]] <- summary(lm(y ~ ., data_y[ , c("i.lm", predictors_i)]))
#data_y <- data_4
}
Below is the error code that I am getting, with Bulk_Densi being the first variable in predictors_1.1. The error code is that variable lengths differ so I originally thought that my issue was that quotes were being added around "Bulk_Densi" but after trying the NoQuote() function I have not gotten anywehre so I am unsure of where I am going wrong.
Error code that I am getting
Please let me know if I can provide any extra info and thanks in advance for the help! I've already tried the info in How to train several models within a loop for and was struggling with that as well.

How can I load a library in R to call it from Excel with bert-toolkit?

Bert-toolkit is a very nice package to call R functions from Excel. See: https://bert-toolkit.com/
I have used bert-toolkit to call a fitted neuralnet (avNNnet fitted with Caret) within a wrapper function in R from Excel VBA. This runs perfect. This is the code to load the model within the wrapper function in bert-toolkit:
load("D:/my_model_avNNet.rda")
neuraln <- function(x1,x2,x3){
xx <- data.frame(x1,x2,x3)
z <- predict(my_model_avNNET, xx)
z
}
Currently I tried to do this with a fitted GAM (fitted with package mgcv). Although I do not succeed. If I call the fitted GAM from Excel VBA it gives error 2015. If I call the fitted GAM from a cell it gives #VALUE! At the same time the correct outcome of the calculation is shown in the bert-console!
This is the code to load the model in the wrapperfunction in bert-toolkit:
library(mgcv)
load("D:/gam_y_model.rda")
testfunction <- function(k1,k2){
z <- predict(gam_y, data.frame(x = k1, x2 = k2))
print (z)
}
The difference between the avNNnet-model (Caret) and the GAM-model (mgcv) is that the avNNnet-model does NOT need the Caret library to be loaded to generate a prediction, while the GAM-model DOES need the mgcv library to be loaded.
It seems to be not sufficient to load the mgvc-library in the script with the GAM-model which loads the GAM-model in a wrapper function in bert-toolkit, as I did in the code above. Although the correct outcome of the model is shown in the bert-console. It does not generate the correct outcome in Excel.
I wonder how this is possible and can be solved. It seems to me that maybe there are two instances of R running in bert-toolkit.
How can I load the the mgcv-library in such a way that it can be used by the GAM-model within the function called from Excel?
This is some example code to fit the GAM with mgcv and save to model (after running this code the model can uploaded in bert-toolkit with the code above) :
library(mgcv)
# construct some sample data:
x <- seq(0, pi * 2, 0.1)
x2 <- seq(0, pi * 20, 1)
sin_x <- sin(x)
tan_x2 <- tan(x2)
y <- sin_x + rnorm(n = length(x), mean = 0, sd = sd(sin_x / 2))
Sample_data <- data.frame(y,x,x2)
# fit gam:
gam_y <- gam(y ~ s(x) + s(x2), method = "REML")
# Make predictions with the fitted model:
x_new <- seq(0, max(x), length.out = 100)
x2_new <- seq(0, max(x2), length.out = 100)
y_pred <- predict(gam_y, data.frame(x = x_new, x2 = x2_new))
# save model, to load it later in bert-toolkit:
setwd("D:/")
save(gam_y, file = "gam_y_model.rda")
One of R's signatures is method dispatching where users call the same named method such as predict but internally a different variant is run such as predict.lm, predict.glm, or predict.gam depending on the model object passed into it. Therefore, calling predict on an avNNet model is not the same predict on a gam model. Similarly, just as the function changes due to the input, so does the output change.
According to MSDN documents regarding the Excel #Value! error exposed as Error 2015:
#VALUE is Excel's way of saying, "There's something wrong with the way your formula is typed. Or, there's something wrong with the cells you are referencing."
Fundamentally, without seeing actual results, Excel may not be able to interpret or translate into Excel range or VBA type the result R returns from gam model especially as you describe R raises no error.
For example, per docs, the return value of the standard predict.lm is:
predict.lm produces a vector of predictions or a matrix of predictions...
However, per docs, the return value of predict.gam is a bit more nuanced:
If type=="lpmatrix" then a matrix is returned which will give a vector of linear predictor values (minus any offest) at the supplied covariate values, when applied to the model coefficient vector. Otherwise, if se.fit is TRUE then a 2 item list is returned with items (both arrays) fit and se.fit containing predictions and associated standard error estimates, otherwise an array of predictions is returned. The dimensions of the returned arrays depends on whether type is "terms" or not: if it is then the array is 2 dimensional with each term in the linear predictor separate, otherwise the array is 1 dimensional and contains the linear predictor/predicted values (or corresponding s.e.s). The linear predictor returned termwise will not include the offset or the intercept.
Altogether, consider adjusting parameters of your predict call to render a numeric vector for easy Excel interpretation and not a matrix/array or some other higher dimension R type that Excel cannot render:
testfunction <- function(k1,k2){
z <- mgcv::predict.gam(gam_y, data.frame(x = k1, x2 = k2), type=="response")
return(z)
}
testfunction <- function(k1,k2){
z <- mgcv::predict.gam(gam_y, data.frame(x = k1, x2 = k2), type=="lpmatrix")
return(z)
}
testfunction <- function(k1,k2){
z <- mgcv::predict.gam(gam_y, data.frame(x = k1, x2 = k2), type=="linked")
return(z$fit) # NOTICE fit ELEMENT USED
}
...
Further diagnostics:
Check returned object of predict.glm with str(obj) and class(obj)/ typeof(obj) to see dimensions and underlying elements and compare with predict in caret;
Check if high precision of decimal numbers is the case such as Excel's limits of 15 decimal points;
Check amount of data returned (exceeds Excel's sheet row limit of 220 or cell limit of 32,767 characters?).

R won't recognize column names as an object

I'm trying to build a histogram of residual values, however the first step I'm taking to do that is to run a linear model. R will not recognize the column name as an object.
The first three lines of code run fine. The second two give me an error saying the object area_ha cant be found, however, it is one of eight column titles in my data. Any advice on creating a linear model and a histogram to graph residuals would also be very helpful.
dat<-read.csv("/Users/sara/Desktop/birdsinforest.csv", header=TRUE)
linearmodel=lm(abundance ~ area_ha, data = dat)
summary(linearmodel)
area_ha$abundance_predicted = predict(linearmodel)
area_ha$residual = area_ha$abundance - area_ha$abundance_predicted
This is the error I get after running the last two lines of code:
Error in area_ha$abundance_predicted = predict(linearmodel) :
object 'area_ha' not found
Your code:
dat<-read.csv("/Users/sara/Desktop/birdsinforest.csv", header=TRUE)
linearmodel=lm(abundance ~ area_ha, data = dat)
summary(linearmodel)
area_ha$abundance_predicted = predict(linearmodel)
area_ha$residual = area_ha$abundance - area_ha$abundance_predicted
In the above code, area_ha seems like a variable (column name) and not data.frame since you're using it to fit a linear model. You should try the last two lines of code as below:
dat$abundance_predicted <- predict(linearmodel)
dat$residual <- dat$abundance - dat$abundance_predicted

R caret nnet package

I have two R objects as below.
matrix "datamatrix" - 200 rows and 494 columns: these are my x variables
dataframe Y. Y$V1 is my Y variable. I have converted column V1 to a factor I am building a classification model.
I want to build a neural network and I ran below command.
model <- train(Y$V1 ~ datamatrix, method='nnet', linout=TRUE, trace = FALSE,
#Grid of tuning parameters to try:
tuneGrid=expand.grid(.size=c(1,5,10),.decay=c(0,0.001,0.1)))
I got an error - " argument "data" is missing, with no default"
Is there a way for caret package to understand that I have my X variables in one R object and Y variable in other? I dont want to combined two data objects and then write a formula as the formula will be too long
Y~x1+x2+x3.................x199+x200....x493+x494
The argument "data" is missing error is addressed by adding a data = datamatrix argument to the train call. The way I would do it would be something like:
datafr <- as.data.frame(datamatrix)
# V1 is the first column name if dimnames aren't specified
datafr$V1 <- as.factor(datafr$V1)
model <- train(V1 ~ ., data = datafr, method='nnet',
linout=TRUE, trace = FALSE,
tuneGrid=expand.grid(.size=c(1,5,10),.decay=c(0,0.001,0.1)))
Now you don't have to pull your response variable out separately.
The . identifier allows inclusion of all variables from datafr (see here for details).

lm function throws an error in terms.formula() in R

I am trying to run linear modelling on the training data frame, but it is not giving me the output.
It gives me an error saying
Error in terms.formula(formula, data = data) :
'.' in formula and no 'data' argument
Code
n <- ncol(training)
input <- as.data.frame(training[,-n])
fit <- lm(training[,n] ~.,data = training[,-n])
There's no need to remove the column from the data to perform this operation, and it's best to use names.
Say that your last column is called response. Then run this:
lm(response ~ ., data=training)
It's hard to say that this is the formula that you need. If you provide a reproducible example, that will become clear.

Resources