Context
I have data frame with multiple columns and i have to do regression between alternate columns (like between 1&2, 3&4) and predict using a test data set and then find residuals. I do not want to reference each column using column name (like target.data$nifty), hence I am using data matrix.
Problem
When i predict using a data matrix, I am getting the following error:
number of items to replace is not a multiple of replacement length
I know my training data set has 255 rows and test data set has 50 rows but it should be able to predict on test data set and give me 50 predicted values, but it is not.
b is a matrix having training data set of 255 rows and 8 columns and t is a matrix having test data set of 50 rows and 8 columns.
I tried using matrix directly as newdata in predict but it was giving following error:
Error in eval(predvars, data, env) : numeric 'envir' arg not of
length one
... so i converted it into a data frame. Please suggest how can I use matrix inside predict.
Here's the code i am using:
b<-as.matrix(target.data)
t<-as.matrix(target.test)
t_pred <- matrix(,nrow = 50,ncol = 8)
t_res <- matrix(,nrow = 50,ncol = 8)
for(i in 1:6) {
if (!i %% 2) {
t_model <- lm(b[,i] ~ b[,i])
t_pred[,i] <- predict(t_model, newdata=data.frame(t[,i]), type = 'response')
t_res[,i] <- t_pred[,i] - t[,i]
}
}
Related
I am carrying out PGLS between a trait and 21 environmental variables for a clade of plant species. I am using a loop to do this 21 times, once for each of the environmental variables, and extract the p-values and some other values into a results matrix.
When normally carrying each PGLS individually I will refer to the variables by their column names, for example:
pgls(**trait1**~**meanrainfall**, data=caperobject)
But in order to loop this process for multiple environmental variables, I am referring to the variables by their column position in the data frame (which is in the form of the caper object for PGLS) instead of their column name:
pgls(**caperobject[,2]**~**caperobject[,5]**, data=caperobject)
This returns the error:
Error in model.frame.default(formula, data$data, na.action = na.pass) :
invalid type (list) for variable 'caperobject[, 2]'
This is not a problem when running a linear regression using the original data frame -- referring to the variables by their column name only produces this error when using the caper object as the data using PGLS. Does this way of referring to the column names not work for caper objects? Is there another way I could refer to the column names so I can incorporate them into a PGLS loop?
Your solution is to use caperobject$data[,2] ~ caperobject$data[,5], because comparative.data class is a list with the trait values located in the list data. Here is an example:
library(ape)
library(caper)
# generate random data
seed <- 245937
tr <- rtree(10)
dat <- data.frame(taxa = tr$tip.label,
trait1 = rTraitCont(tr, root.value = 3),
meanrainfall = rnorm(10, 50, 10))
# prepare a comparative.data structure
caperobject <- comparative.data(tr, dat, taxa, vcv = TRUE, vcv.dim = 3)
# run PGLS
pgls(trait1 ~ meanrainfall, data = caperobject)
pgls(caperobject$data[, 1] ~ caperobject$data[, 2], data = caperobject)
Both options return identical values for the intercept = 3.13 and slope = -0.003.
A good practice in problems with data format is to check, how the data are stored with str(caperobject).
I am trying to apply table function but I got this error, so I think that because the test is a factor and the prediction is a matrix:
Error in table(rfe_nB_test_folds[, 7], rfe_nB_predict) :
all arguments must have the same length
for that, I need to convert prediction result to factor so I can use it on table function, but I get this error and I think that because of 10 cross-validation because when I try it without 10 cross-validation it works:
Error in [.default(rfe_nB_predict, , 2) :
incorrect number of dimensions
My code:
set.seed(100)
rfe_nB_folds<-createFolds(BC_bind$outcome, k=10) #create folds
rfe_nB_fun <- lapply (rfe_nB_folds, function(x){
rfe_nB_traing_folds<-BC_bind[-x,]
rfe_nB_test_folds<-BC_bind[x,]
#build the model
rfe_nB_model<-naiveBayes(outcome ~ ., data = rfe_nB_traing_folds) #test the model
rfe_nB_predict<-predict(rfe_nB_model,rfe_nB_test_folds[-7],type="raw")
rfe_nB_predict<-as.factor(rfe_nB_predict)
CR<-roc.curve(rfe_nB_test_folds[,7], rfe_nB_predict[,2])
print(CR)
rfe_nB_table<-table(rfe_nB_test_folds[,7],rfe_nB_predict)
rfe_nB_confusionMatrix<-confusionMatrix(rfe_nB_table,positive = "R") #to see the matrex of echo flods
return (rfe_nB_confusionMatrix$table)
})
I'm used specific columns so I saved them on BC_bind as shown in the code.
Top_6featurs <- wpdc[,c(33,11,10,32,29,12)] #column number of top 6 featur
BC_bind <- data.frame(cbind(Top_6featurs , wpdc$outcome))
I have a dataframe dfab that contains 2 columns that I used as argument to generate a series of linear models as following:
models = list()
for (i in 1:10){
models[[i]] = lm(fc_ab10 ~ (poly(nUs_ab, i)), data = dfab)
}
dfab has 32 observations and I want to predict fc_ab10 for only 1 value.
I thought of doing so:
newdf = data.frame(newdf = nUs_ab)
newdf[] = 0
newdf[1,1] = 56
prediction = predict(models[[1]], newdata = newdf)
First I tried writing newdf as a dataframe with only one position, but since there are 32 in the dataset on which the model was built, I thought I had to provide at least 32 points as well. I don't think this is necessary though.
Every time I run that piece of code I am given the following error:
Error: variable 'poly(nUs_ab, i) was fitted with type “nmatrix.1” but type “numeric” was supplied.
In addition: Warning message:
In Z/rep(sqrt(norm2[-1L]), each = length(x)) :
longer object length is not a multiple of shorter object length
I thought all I need to use predict was a LM model, predictors (the number 56) given in a column-named dataframe. Obviously, I am mistaken.
How can I fix this issue?
Thanks.
newdf should be a data.frame with column name nUs_ab, otherwise R won't be able to know which column to operate upon (i.e., generate the prediction design matrix). So the following code should work
newdf = data.frame(nUs_ab = 56)
prediction = predict(models[[1]], newdata = newdf)
I'm trying to predict some data from PCA using leave-one-out (LOO) cross validation.
The prcomp goes well, however when I come to predict the function gets upset
error: 'newdata' must be a matrix or data frame
because I'm supplying a vector (i.e. a single row) and not a matrix (i.e. multiple rows).
I've tried as.data.frame and as.matrix and various varieties thereof but I still get errors
error: 'newdata' does not have named columns matching one or more of the original columns`
In my example here loo is the LOO index and mydata and myinfo contain the data and metadata respectively.
tdata = mydata[-loo,]
tinfo = myinfo[-loo,]
vdata = mydata[loo,]
vinfo = myinfo[loo,]
p = prcomp( tdata )
predict(p, newdata = vdata )
Nevermind, found it:
predict(p, newdata = as.data.frame(t(vdata)) )
Using "stackloss" data in R, I created a regression model as seen below:
stackloss.lm = lm(stack.loss ~ Air.Flow + Water.Temp + Acid.Conc.,data=stackloss)
stackloss.lm
newdata = data.frame(Air.Flow=stackloss$Air.Flow, Water.Temp= stackloss$Water.Temp, Acid.Conc.=stackloss$Acid.Conc.)
Suppose I get a new data set and would need predict its "stack.loss" based on the previous model as seen below:
#suppose I need to used my model on a new set of data
stackloss$predict1[-1] <- predict(stackloss.lm, newdata)
I get this error:
Error in `$<-.data.frame`(`*tmp*`, "predict1", value = numeric(0)) :
replacement has 0 rows, data has 21
Is their a way to used the predict function on different data set with the same columns but different rows?
Thanks in advance.
You can predict into a new data set of whatever length you want, you just need to make sure you assign the results to an existing vector of appropriate size.
This line causes a problem because
stackloss$predict1[-1] <- predict(stackloss.lm, newdata)
because you can't assign and subset a non-existing vector at the same time. This also doesn't work
dd <- data.frame(a=1:3)
dd$b[-1]<-1:2
The length of stackloss which you used to fit the model will always be the same length so re-assigning new values to that data.frame doesn't make sense. If you want to use a smaller dataset to predict on, that's fine
stackloss.lm = lm(stack.loss ~ Air.Flow + Water.Temp + Acid.Conc.,data=stackloss)
newdata = head(data.frame(Air.Flow=stackloss$Air.Flow, Water.Temp= stackloss$Water.Temp, Acid.Conc.=stackloss$Acid.Conc.),5)
predict(stackloss.lm, newdata)
1 2 3 4 5
38.76536 38.91749 32.44447 22.30223 19.71165
Since the result has the same number of values as newdata has rows (n=5), it makes sense to attach these to newdata. It would not make sense to attach to stackloss because that has a different number of rows (n=21)
newdata$predcit1 <- predict(stackloss.lm, newdata)