Non-linear random-effects regression with multiplication of coefficients in R - r

I have two regression models without random effects: one is OLS using lm, the other includes multiplication of coefficients using nle.
I wish to add individual-level random effects to both. I've managed to do this for the OLS function using the lme4 package, but haven't been able to find a way to do it for the multiplicative model.
The following code produces a dataset with similar structure to the one I am working on:
df <- data.frame(id = rep(1:1000, each=10), jit = rep(rnorm(1000, 0, 0.2), each = 10), a = sample(1:5, 10000, T), b = sample(1:5, 10000,T), c = sample(1:5, 10000, T))
df <- cbind(df, model.matrix(~ as.factor(a) + as.factor(b) + as.factor(c), data.frame(rbind(as.matrix(df), t(matrix(rep(1:5, each = 5), nrow=5)))))[1:nrow(df),2:13])
colnames(df)[6:17] <- (dim_dummies <- as.vector(outer(2:5, letters[1:3], function(x, y) paste(y, x, sep=""))))
true_vals <- list(vL2 = 0.4, vL3 = 0.5, vL4 = 0.8, vA = 0.7, vB = 1.1, vC = 0.9)
attach(df)
attach(true_vals)
df$val <-
(a2 * vA + b2*vB + c2*vC) * vL2 +
(a3 * vA + b3*vB + c3*vC) * vL3 +
(a4 * vA + b4*vB + c4*vC) * vL4 +
(a5 * vA + b5*vB + c5*vC) + runif(1, -.2, .2) + jit
detach(true_vals)
detach(df)
df[1:15, ]
id jit a b c a2 a3 a4 a5 b2 b3 b4 b5 c2 c3 c4 c5 val
1 1 -0.14295 4 4 1 0 0 1 0 0 0 1 0 0 0 0 0 1.1698
2 1 -0.14295 5 1 4 0 0 0 1 0 0 0 0 0 0 1 0 1.1498
3 1 -0.14295 5 4 4 0 0 0 1 0 0 1 0 0 0 1 0 2.0298
4 1 -0.14295 5 1 5 0 0 0 1 0 0 0 0 0 0 0 1 1.3298
5 1 -0.14295 5 4 2 0 0 0 1 0 0 1 0 1 0 0 0 1.6698
6 1 -0.14295 1 5 1 0 0 0 0 0 0 0 1 0 0 0 0 0.8298
7 1 -0.14295 3 2 5 0 1 0 0 1 0 0 0 0 0 0 1 1.4198
8 1 -0.14295 3 2 1 0 1 0 0 1 0 0 0 0 0 0 0 0.5198
9 1 -0.14295 3 2 4 0 1 0 0 1 0 0 0 0 0 1 0 1.2398
10 1 -0.14295 5 3 3 0 0 0 1 0 1 0 0 0 1 0 0 1.4298
11 2 -0.01851 4 5 3 0 0 1 0 0 0 0 1 0 1 0 0 1.9643
12 2 -0.01851 2 1 3 1 0 0 0 0 0 0 0 0 1 0 0 0.5843
13 2 -0.01851 2 1 3 1 0 0 0 0 0 0 0 0 1 0 0 0.5843
14 2 -0.01851 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 -0.1457
15 2 -0.01851 2 3 1 1 0 0 0 0 1 0 0 0 0 0 0 0.6843
...
a, b, and c represent scores on three 1:5 dimension scales. a2 through c5 are dummy variables representing levels 2:5 on the same scales. There are 10 observations per individual (id). val is a proxy for the score I wish to predict using the regression models. (The values in the actual data may not correspond to the structure here, however.)
I have two regression models without random effects. One is a regular OLS using the 12 dummy variables as predictors of val:
additive.formula <- as.formula("val ~
a2 + a3 + a4 + a5 +
b2 + b3 + b4 + b5 +
c2 + c3 + c4 + c5")
fit.additive <- lm(additive.formula, data = df)
The second assumes that the relative distance between the levels is shared for the three dinensions (a,b,c), but that the dimensions differ in terms of scale. That leaves 6 coefficients (cA, cB, cC, cL2, cL3, cL4) + the intercept.
multiplicative.formula <- as.formula(" val ~ intercept +
(a2 * cA + b2*cB + c2*cC) * cL2 +
(a3 * cA + b3*cB + c3*cC) * cL3 +
(a4 * cA + b4*cB + c4*cC) * cL4 +
(a5 * cA + b5*cB + c5*cC)")
multiplicative.start <- list(intercept = 0, cA = 1, cB = 1, cC = 1, cL2 = 1, cL3 = 1, cL4 = 1)
fit.multiplicative <- nls(multiplicative.formula, start=multiplicative.start, data=df, control = list(maxiter = 5000))
Since there are 10 observations per individual, we cannot expect them to be fully independent. Therefore, I wish to add a random effect at the level of individual as defined by the variable id. I've found a way to do that with the lme4 package:
require(lme4)
additive.formula.re <- as.formula("val ~ (1 | id) +
a2 + a3 + a4 + a5 +
b2 + b3 + b4 + b5 +
c2 + c3 + c4 + c5")
fit.additive.re <- lmer(additive.formula.re, data=df)
The question is if it is possible to add random effects on the id variable using a regression model similar to the multiplicative one, maybe with the lme4 or nlme packages? The formula should look something like
multiplicative.formula.re <- as.formula(" val ~ (1 | id) + intercept +
(a2 * cA + b2*cB + c2*cC) * cL2 +
(a3 * cA + b3*cB + c3*cC) * cL3 +
(a4 * cA + b4*cB + c4*cC) * cL4 +
(a5 * cA + b5*cB + c5*cC)")
Any suggestions?

Try nlme. This should be what you need (if I understood correctly):
library(nlme)
fit.multiplicative.nlme <- nlme( model = val ~ intercept +
(a2 * cA + b2*cB + c2*cC) * cL2 +
(a3 * cA + b3*cB + c3*cC) * cL3 +
(a4 * cA + b4*cB + c4*cC) * cL4 +
(a5 * cA + b5*cB + c5*cC),
fixed = intercept + cA +cB + cC + cL2 + cL3 + cL4 ~ 1,
random = intercept ~ 1|id,
start = unlist(multiplicative.start), data=df)
However, this didn't converge when I tried it with the non-reproducible data you provide (you should set a random seed). You could try different settings in nlmeControl.
The below was incorrect:
I don't see a reason for non-linear least squares. Let's revert the dummy encoding:
df$id1 <- seq_len(nrow(df))
df$a1 <- as.integer(rowSums(df[, paste0("a", 2:5)]) == 0)
df$b1 <- as.integer(rowSums(df[, paste0("b", 2:5)]) == 0)
df$c1 <- as.integer(rowSums(df[, paste0("c", 2:5)]) == 0)
library(reshape2)
DFm <- melt(df, id.vars = c("id", "jit", "a", "b", "c", "val", "id1"))
DFm <- DFm[DFm$value == 1,]
DFm$g <- paste0("fac", substr(DFm$variable, 1, 1))
DF <- dcast(DFm, ... ~ g, value.var = "variable")
fit1 <- lm(val ~ faca + facb + facc, data = DF)
#compare results:
coef(fit.multiplicative)
prod(coef(fit.multiplicative)[c("cA", "cL2")])
coef(fit1)["facaa2"]
prod(coef(fit.multiplicative)[c("cA", "cL3")])
coef(fit1)["facaa3"]
As you see, this is basically the same model (differences are due to numerical optimization within nls). And it's easy to add a random intercept to this.

Related

How do you change the x-axis tick labels on plot_model() and format the lines on the graph to be closer together?

I am following the example here:
https://strengejacke.github.io/sjPlot/articles/plot_interactions.html
I copy the following:
library(sjPlot)
library(sjmisc)
library(ggplot2)
data(efc)
theme_set(theme_sjplot())
# make categorical
efc$c161sex <- to_factor(efc$c161sex)
# fit model with interaction
fit <- lm(neg_c_7 ~ c12hour + barthtot * c161sex, data = efc)
And then I do the following:
plot_model(fit, type = "pred", terms = c("c161sex", "barthtot [0, 100]"))
Why does the x-axis ticks show up as "male" and "female" when their values are 1 and 2 in the data frame?
Is there a way to replace the x-axis ticks when using plot_model? I've been adding scale_x_discrete(breaks=c("1","2"), labels=c("male", "female")) in other datasets and it makes my x-axis ticks disappear altogether.
And is it possible to have the lines closer to each other rather than so far apart?
When I use my own dataset (I'm unable to post the whole dataset), I get something that looks like this:
Replication code:
data = read.table(text="
X Z Y
0 1 1
1 0 1
1 0 1
0 1 1
1 1 0
1 0 0
0 0 0
1 1 1
1 1 1
0 0 1
1 0 1
1 1 1
0 1 0
1 0 0
1 0 0
0 1 1
1 1 1
1 0 1
0 0 1
1 1 1
1 1 0
0 0 0
1 0 0
1 1 1
0 1 1
1 0 1
1 0 1
0 1 1
1 1 0
1 0 0", header=TRUE)
data$X <- as.factor(data$X)
data$Z <- as.factor(data$Z)
h <- lm_robust(Y ~ X*Z, data = data)
plot_model(h, type = "pred", terms = c("X", "Z")) +
xlab("Fun Level") + ylab("") + theme_bw() +
theme(legend.title=element_blank()) +
scale_x_discrete(limits = c("Not Fun", "Fun"))
Use scale_x_discrete(limits = c("1", "2")); this will also bring the two categories closer together.
library(sjPlot)
#> Learn more about sjPlot with 'browseVignettes("sjPlot")'.
library(sjmisc)
library(ggplot2)
data(efc)
theme_set(theme_sjplot())
# make categorical
efc$c161sex <- to_factor(efc$c161sex)
# fit model with interaction
fit <- lm(neg_c_7 ~ c12hour + barthtot * c161sex, data = efc)
plot_model(fit, type = "pred", terms = c("c161sex", "barthtot [0, 100]")) +
scale_x_discrete(limits = c("1", "2"))
#> Scale for x is already present.
#> Adding another scale for x, which will replace the existing scale.
NEW EDIT (after additional data/info)
Somehow you should indicate, if the original post is being substantially changed. In this new addition you use a function lm_robust which is from a package estimate`.
Key here is that you must define factor levels of data$X:
levels(data$X) <- list('Not Fun' = 0, "Fun" = 1).
Then you can together with scale_x_discrete() change the axis.ticks.
Within plot_model I have used axis.lim = list(c(.6,2.4), c(-.2,1.5)to tweak the x-axis, so that they come closer together.
library(sjPlot)
#> Learn more about sjPlot with 'browseVignettes("sjPlot")'.
library(sjmisc)
library(ggplot2)
library(estimatr)
data = read.table(text="
X Z Y
0 1 1
1 0 1
1 0 1
0 1 1
1 1 0
1 0 0
0 0 0
1 1 1
1 1 1
0 0 1
1 0 1
1 1 1
0 1 0
1 0 0
1 0 0
0 1 1
1 1 1
1 0 1
0 0 1
1 1 1
1 1 0
0 0 0
1 0 0
1 1 1
0 1 1
1 0 1
1 0 1
0 1 1
1 1 0
1 0 0", header=TRUE)
data$X <- factor(data$X)
levels(data$X) <- list('Not Fun' = 0, "Fun" = 1)
data$Z <- factor(data$Z)
h <- lm_robust(Y ~ X + Z, data = data)
plot_model(h, type ='eff', terms = c("X", "Z"),
axis.lim = list(c(.6,2.4), c(-.2,1.5))
)+
scale_x_discrete(limits = c("0" = "Not Fun", "1" = "Fun"))

R: Simulating Discrete Correlated Data

I am working with the R programming language.
I am trying to simulate random discrete data that contains "correlations" between the variables. For example, this is what I have tried so far (I generated random continuous data with correlations, and converted all values below a certain threshold to 0 else 1):
library(mvtnorm)
n <- 11
A <- matrix(runif(n^2)*2-1, ncol=n)
s <- t(A) %*% A
my_data = MASS::mvrnorm(100, mu = c(rnorm(11,10,1)), Sigma = s)
my_data = data.frame(my_data)
colnames(my_data)[1] <- 'p1'
colnames(my_data)[2] <- 'p2'
colnames(my_data)[3] <- 'p3'
colnames(my_data)[4] <- 'p4'
colnames(my_data)[5] <- 'p5'
colnames(my_data)[6] <- 'p6'
colnames(my_data)[7] <- 'p7'
colnames(my_data)[8] <- 'p8'
colnames(my_data)[9] <- 'p9'
colnames(my_data)[10] <- 'p10'
colnames(my_data)[11] <- 'result'
my_data[my_data < 9] <- 0
my_data[my_data > 9] <- 1
p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 result
1 1 1 1 0 1 1 1 0 0 0 0
2 0 1 1 1 1 0 1 1 1 1 1
3 1 1 1 0 1 0 1 1 1 1 1
4 1 1 1 0 1 1 1 1 1 1 1
5 0 1 1 1 1 0 1 1 0 0 0
6 1 0 1 0 1 1 1 0 1 1 1
I am not sure if I have done this correctly - sure, I have simulated random discrete data, but I am not sure if I have preserved the correlation structure within the data. For instance, I would have liked there to be correlation patterns such as:
When p1 = p5 = p9 = 1 -> "results" are more likely to be 1 (i.e. take all rows where p1 = p5 = p9 = 1 and measure the percentage of 1's in the results column)
When p3 = p4 = 0 and p9 = 1 -> "results" are more likely to be 0
etc.
Is there some other way to do this?
Thanks!
If you are happy with p1 through p10 and just want to use your stated rules to generate the result column, then you do a kind of reverse logistic regression. First of all, set up your rules to give you numerical results. Here, we get a 1 if p1 = p5 = p9 = 1, and we get -1 if p3 = 0, p4 = 0, p9 = 1:
log_odds <- with(my_data, p1 * p5 * p9)
log_odds <- with(my_data, result - (1 - p3) * (1 - p4) * p9)
Now we convert these to probabilities of getting a 1 in our results column:
odds <- exp(log_odds)
probs <- odds / (1 + odds)
Finally, we use probs to generate a binomial sample:
my_data$result <- rbinom(nrow(my_data), size = 1, prob = probs)
We can see that overall our sample has about a 50% chance of having a 1 or 0:
table(my_data$result)
#> 0 1
#> 47 53
But the odds of a 1 are much increased when p1 = p5 = p9 = 1
table(my_data$result[with(my_data, p1 == 1 & p5 == 1 & p9 == 1)])
#> 0 1
#> 3 18
It is possible to control the background probability and strength of correlations by adjusting the weightings for log_odds

One-hot encoding using model.matrix

There is something I do not understand in model.matrix. When I enter a single binary variable without an intercept it returns two levels.
> temp.data <- data.frame('x' = sample(c('A', 'B'), 1000, replace = TRUE))
> temp.data.table <- model.matrix( ~ 0 + x, data = temp.data)
> head(temp.data.table)
xA xB
1 1 0
2 0 1
3 0 1
4 0 1
5 1 0
6 0 1
However, when I enter another binary level, it creates only 3 columns. Why is that? What makes the behavior of the function suddenly different? and how can I avoid it?
> temp.data <- data.frame('x' = sample(c('A', 'B'), 1000, replace = TRUE),
+ 'y' = sample(c('J', 'D'), 1000, replace = TRUE))
> temp.data.table <- model.matrix( ~ 0 + x + y, data = temp.data)
> head(temp.data.table)
xA xB yJ
1 0 1 0
2 0 1 1
3 0 1 1
4 0 1 0
5 1 0 1
6 0 1 0
You need to work with factors and set the contrasts to FALSE. Try this:
n <- 10
temp.data <- data.frame('x'=sample(c('A', 'B'), n, replace=TRUE),
'y'=factor(sample(c('J', 'D'), n, replace=TRUE)))
model.matrix( ~ 0 + x + y, data=temp.data,
contrasts=list(y=contrasts(temp.data$y, contrasts=FALSE)))
# xA xB yD yJ
# 1 0 1 1 0
# 2 1 0 0 1
# 3 0 1 1 0
# 4 1 0 0 1
# 5 0 1 0 1
# 6 1 0 1 0
# 7 1 0 1 0
# 8 0 1 1 0
# 9 0 1 0 1
# 10 0 1 1 0
# attr(,"assign")
# [1] 1 1 2 2
# attr(,"contrasts")
# attr(,"contrasts")$x
# [1] "contr.treatment"
#
# attr(,"contrasts")$y
# D J
# D 1 0
# J 0 1
To understand why this happens, try:
contrasts(temp.data$y)
# J
# D 0
# J 1
contrasts(temp.data$y, contrasts=F)
# D J
# D 1 0
# J 0 1
With your x variable this happens automatically by setting 0 + to remove the intercept. (Actually x also should be coded as factor).
The reason is, that in linear regression the levels of factor variables are usually compared to a reference level (which you could change using relevel). In your model matrix, with 0 + you remove the intercept for your first variable but not to the following (try model.matrix( ~ 0 + y + x, data=temp.data) where you get only one x but to y). This is determined in the standard contrasts setting using treatment contrasts by default.
You may want to read a relevant post of Rose Maier (2015) explaining this in great detail:
Contrasts in R
You need to reset the contrasts of the factor variables. See this post.
temp.data <- data.frame('x' = sample(c('A', 'B'), 1000, replace = TRUE),
+ 'y' = sample(c('J', 'D'), 1000, replace = TRUE))
dat = model.matrix(~ -1 +., data=temp.data, contrasts.arg = lapply(temp.data[,1:2], contrasts, contrasts=FALSE))
head(dat)
xA xB yD yJ
1 0 1 0 1
2 1 0 0 1
3 1 0 0 1
4 1 0 0 1
5 0 1 1 0
6 0 1 0 1

Difference between categorical variables (factors) and dummy variables

I was running a regression using categorical variables and came across this question. Here, the user wanted to add a column for each dummy. This left me quite confused because I though having long data with the column including all the dummies stored using as.factor() was equivalent to having dummy variables.
Could someone explain the difference between the following two linear regression models?
Linear Model 1, where Month is a factor:
dt_long
Sales Period Month
1: 0.4898943 1 M1
2: 0.3097716 1 M1
3: 1.0574771 1 M1
4: 0.5121627 1 M1
5: 0.6650744 1 M1
---
8108: 0.5175480 24 M12
8109: 1.2867316 24 M12
8110: 0.6283875 24 M12
8111: 0.6287151 24 M12
8112: 0.4347708 24 M12
M1 <- lm(data = dt_long,
fomrula = Sales ~ Period + factor(Month)
Linear Model 2 where each month is an indicator variable:
dt_wide
Sales Period M1 M2 M3 M4 M5 M6 M7 M8 M9 M10 M11 M12
1: 0.4898943 1 1 0 0 0 0 0 0 0 0 0 0 0
2: 0.3097716 1 1 0 0 0 0 0 0 0 0 0 0 0
3: 1.0574771 1 1 0 0 0 0 0 0 0 0 0 0 0
4: 0.5121627 1 1 0 0 0 0 0 0 0 0 0 0 0
5: 0.6650744 1 1 0 0 0 0 0 0 0 0 0 0 0
---
8108: 0.5175480 24 0 0 0 0 0 0 0 0 0 0 0 1
8109: 1.2867316 24 0 0 0 0 0 0 0 0 0 0 0 1
8110: 0.6283875 24 0 0 0 0 0 0 0 0 0 0 0 1
8111: 0.6287151 24 0 0 0 0 0 0 0 0 0 0 0 1
8112: 0.4347708 24 0 0 0 0 0 0 0 0 0 0 0 1
M2 <- lm(data = data_wide,
formula = Sales ~ Period + M1 + M2 + M3 + ... + M11 + M12
Judging by this previously asked question, both models seem exactly the same. However, after running both models, I noticed that M1 returns 11 dummy estimators (because M1 is used as the reference level), while M2 returns 12 dummies.
Is one model better than the other? Is M1 more efficien? Can I set the reference level in M1 to make both models exactly equivalent?
Defining a model as in M1 is just a shortcut of including dummy variables: if you wanted to compute those regression coefficients by hand, clearly they'd have to be numeric.
Now something that perhaps you didn't notice about M2 is that one of the dummies should have a NA coefficient. That is because you manually included all of them and left the intercept. In this way we have a perfect collinearity issue. By not including one of the dummies or adding -1 to eliminate the constant term everything would be fine.
Some examples. Let
y <- rnorm(100)
x0 <- rep(1:0, each = 50)
x1 <- rep(0:1, each = 50)
x <- factor(x1)
In this way x0 and x1 is a decomposition of x. Then
## Too much
lm(y ~ x0 + x1)
# Call:
# lm(formula = y ~ x0 + x1)
# Coefficients:
# (Intercept) x0 x1
# -0.15044 0.07561 NA
## One way to fix it
lm(y ~ x0 + x1 - 1)
# Call:
# lm(formula = y ~ x0 + x1 - 1)
# Coefficients:
# x0 x1
# -0.07483 -0.15044
## Another one
lm(y ~ x1)
# Call:
# lm(formula = y ~ x1)
# Coefficients:
# (Intercept) x1
# -0.07483 -0.07561
## The same results
lm(y ~ x)
# Call:
# lm(formula = y ~ x)
# Coefficients:
# (Intercept) x1
# -0.07483 -0.07561
Ultimately all the models contain the same amount of information, but in the case of multicollinearity we face the issue of identification.
Improper dummy coding.
When you change a categorical variable into dummy variables, you will have one fewer dummy variable than you had categories. That’s because the last category is already indicated by having a 0 on all other dummy variables. Including the last category just adds redundant information, resulting in multicollinearity. So always check your dummy coding if it seems you’ve got a multicollinearity problem.

How to create a loop that will add new variables to a pre define glm model

I would like to create a procedure that will add per each loop a new variable (from a pool of variables) to a glm model that allready contains few of the variables that need to be part of the final model.I than would like to have the results of the loop in a list that will contain the glm formula and results.I know how to do it manually (code is written below) but I would be happy to know how to do it automaticaly.
Here is a toy dataset and the relevant code to do the task manually:
dat <- read.table(text = "target birds wolfs Country
0 21 7 a
0 8 4 b
1 2 5 c
1 2 4 a
0 8 3 a
1 1 12 a
1 7 10 b
1 1 9 c",header = TRUE)
#birds is a mandatory variable so I'll need to add one of the other variables in addition to birds
glm<-glm(target~birds,data=dat)
dat$glm_predict_response <- ifelse(predict(glm,newdata=dat, type="response")>.5, 1, 0)
xtabs(~target + glm_predict_response, data = dat)
glm_predict_response
target 0 1
0 1 2
1 0 5
glm_predict_response
prop.table(xtabs(~target + glm_predict_response, data = dat), 2)
target 0 1
0 1.0000000 0.2857143
1 0.0000000 0.7142857
#manually I would add the next variable (wolfs) to the model and look at the results:
glm<-glm(target~birds+wolfs,data=dat)
dat$glm_predict_response <- ifelse(predict(glm,newdata=dat, type="response")>.5, 1, 0)
xtabs(~target + glm_predict_response, data = dat)
glm_predict_response
target 0 1
0 3 0
1 0 5
prop.table(xtabs(~target + glm_predict_response, data = dat), 2)
glm_predict_response
target 0 1
0 1 0
1 0 1
In the next loop I would add the variable "country" and do the same procedure, In the real life I have hundreds of variables so turning it to an automatic proccess would be great.
I would do it using update to update the formula each time in the loop:
#initiate formula
myform <- target~1
for ( i in c('birds', 'wolfs' , 'Country')) {
#update formula each time in the loop with the above variables
#this line below is practically the only thing I changed
myform <- update(myform, as.formula(paste('~ . +', i)))
glm<-glm(myform,data=dat)
dat$glm_predict_response <- ifelse(predict(glm,newdata=dat, type="response")>.5, 1, 0)
print(myform)
print(xtabs(~ target + glm_predict_response, data = dat))
print(prop.table(xtabs(~target + glm_predict_response, data = dat), 2))
}
Output:
target ~ birds
glm_predict_response
target 0 1
0 1 2
1 0 5
glm_predict_response
target 0 1
0 1.0000000 0.2857143
1 0.0000000 0.7142857
target ~ birds + wolfs
glm_predict_response
target 0 1
0 3 0
1 0 5
glm_predict_response
target 0 1
0 1 0
1 0 1
target ~ birds + wolfs + Country
glm_predict_response
target 0 1
0 3 0
1 0 5
glm_predict_response
target 0 1
0 1 0
1 0 1
You can try something like
list_1=list(NA)
list_2=list(NA)
for (i in 2 :ncol(dat)){
dat1=dat[,1:i]
glm<-glm(target~.,data=dat1)
dat1$glm_predict_response <- ifelse(predict(glm,newdata=dat1, type="response")>.5, 1, 0)
list_1[[i-1]]=xtabs(~target + glm_predict_response, data = dat1)
names(list_1)[i-1]=do.call(paste,as.list(colnames(dat1)[c(-1,-ncol(dat1))]))
list_2[[i-1]]=prop.table(xtabs(~target + glm_predict_response, data = dat1), 2)
names(list_2)[i-1]=do.call(paste,as.list(colnames(dat1)[c(-1,-ncol(dat1))]))}
But you need to have col in right order.

Resources