0

Following this other question (Get p-value about contrast hypothesis for rectangular matrix) I am trying to run the following code in R, but the line:

colnames(posmat) <- "pos_c1"

causes an error when calling the function summary().

Error in `row.names<-.data.frame`(`*tmp*`, value = value) : 
  duplicate 'row.names' are not allowed
In addition: Warning message:
non-unique value when setting 'row.names': ‘Pos’ 

Does anybody knows why this error comes up? Here the MWE:

library(lme4)
library(lmerTest)
library(corpcor)

database <- data.frame(
Clos=factor(c(4,4,1,4,4,3,2,1,2,1,2,2,4,3,1,2,1,4,1,3,2,2,4,4,4,4,2,1,4,2,2,1,4,2,4,2,1,4,4,3)),
Pos=factor(c(2,4,1,2,5,6,7,2,2,2,5,6,3,3,3,8,5,3,4,2,1,4,3,3,2,6,1,8,3,7,5,7,8,3,6,6,1,6,3,7)),
RF=c(8,6,2,9,7,1,7,6,3,4,6,4,5,2,5,5,3,4,1,3,1,2,3,1,2,2,3,1,8,5,2,2,7,1,9,4,5,6,4,2),
Score=c(4,3,3,5,4,3,2,4,5,2,2,3,3,4,4,4,3,2,3,3,5,4,3,4,4,2,3,4,3,4,1,2,2,2,3,4,5,3,1,2)
)
clos_c1 = c(0,0,-1,1)
clos_c2 = c(0,-1,0,1)
clos_c3 = c(-1,0,0,1)
closmat.temp = rbind(constant = 1/4,clos_c1,clos_c2,clos_c3)
closmat = solve(closmat.temp)
closmat = closmat[, -1]
closmat
pos_c1 = c(1/2,1/2,-1/6,-1/6,-1/6,-1/6,-1/6,-1/6)
posmat.temp = rbind(pos_c1)
posmat = pseudoinverse(posmat.temp)
colnames(posmat) <- "pos_c1"
contrasts(database$Clos) = closmat
contrasts(database$Pos) = posmat
model = lmer(Score~Clos+Pos+(1|RF), data = database, REML = TRUE)
summary(model)
TakeMeToTheMoon
  • 527
  • 1
  • 8
  • 25
  • If you change this `lmer` to `lme4::lmer` it works. But I am not sure which lmer function you want. – SeGa Jun 01 '18 at 18:55

1 Answers1

2

The problem is that when you run the model, you have the contrasts(database$Pos) without colnames but just one. You can see that by running your model variable and you will see 6 variables with the name "Pos". This causes trouble in reading the summary() command. Just by adding the line

colnames(contrasts(database$Pos))<-c("pos1","pos2","pos3","pos4","pos5","pos6","pos7")

after the creation of your contrasts(database$Pos) <- posmat your code will work. Feel free to put the colnames you require.

The whole code is as follows then:

library(lme4)
library(lmerTest)
library(corpcor)

database <- data.frame(
  Clos=factor(c(4,4,1,4,4,3,2,1,2,1,2,2,4,3,1,2,1,4,1,3,2,2,4,4,4,4,2,1,4,2,2,1,4,2,4,2,1,4,4,3)),
  Pos=factor(c(2,4,1,2,5,6,7,2,2,2,5,6,3,3,3,8,5,3,4,2,1,4,3,3,2,6,1,8,3,7,5,7,8,3,6,6,1,6,3,7)),
  RF=c(8,6,2,9,7,1,7,6,3,4,6,4,5,2,5,5,3,4,1,3,1,2,3,1,2,2,3,1,8,5,2,2,7,1,9,4,5,6,4,2),
  Score=c(4,3,3,5,4,3,2,4,5,2,2,3,3,4,4,4,3,2,3,3,5,4,3,4,4,2,3,4,3,4,1,2,2,2,3,4,5,3,1,2)
)
clos_c1 = c(0,0,-1,1)
clos_c2 = c(0,-1,0,1)
clos_c3 = c(-1,0,0,1)
closmat.temp = rbind(constant = 1/4,clos_c1,clos_c2,clos_c3)
closmat = solve(closmat.temp)
closmat = closmat[, -1]
closmat
pos_c1 = c(1/2,1/2,-1/6,-1/6,-1/6,-1/6,-1/6,-1/6)
posmat.temp = rbind(pos_c1)
posmat <- pseudoinverse(posmat.temp)
colnames(posmat) <- "pos_c1"
contrasts(database$Clos) <- closmat
contrasts(database$Pos) <- posmat
##NEW LINE
colnames(contrasts(database$Pos))<-c("pos1","pos2","pos3","pos4","pos5","pos6","pos7")
model <- lmer(Score~Clos+Pos+(1|RF), data = database, REML = TRUE)
summary(model)

I hope it helps. Cheers!

Carles
  • 2,731
  • 14
  • 25
  • It sort of helps. Thanks! I mean, I guess that now "pos1" is my "pos_c1", correct? From what I understand, After creating a rectangular posmat, the contrasts() function transform it in an equivalent squared matrix, where the first column is my contrast, so that "pos1" becomes the new column name of my constrast. Am I wrong? – TakeMeToTheMoon Jun 02 '18 at 14:31
  • As far as I understand, you are right. I wrote "pos1" referencing your "pos_c1". The `contrasts()` function is required when one fits linear models with factors (i.e. categorical variables) as explanatory variables. It specifies how the levels of the factors will be coded into a family of numeric dummy variables for fitting the model. The full explanation can be found here: https://stackoverflow.com/a/2354304/9513536, Cheers ! – Carles Jun 05 '18 at 13:26