SDQ: Generating scores in R

The scoring algorithm is based on the 25 variables plus impact items for each questionnaire. The algorithm expects to find these variables with specific names: the first letter of each variable name is 'p' for the parent SDQ, 's' for the self-report SDQ and 't' for the teacher SDQ. After this first letter, the variable names are as follows:

consid =Item 1 : considerate
restles =Item 2 : restless
somatic =Item 3 : somatic symptoms
shares =Item 4 : shares readily
tantrum =Item 5 : tempers
loner =Item 6 : solitary
obeys =Item 7 : obedient
worries =Item 8 : worries
caring =Item 9 : helpful if someone hurt
fidgety =Item 10 : fidgety
friend =Item 11 : has good friend
fights =Item 12 : fights or bullies
unhappy =Item 13 : unhappy
popular =Item 14 : generally liked
distrac =Item 15 : easily distracted
clingy =Item 16 : nervous in new situations
kind =Item 17 : kind to younger children
lies =Item 18 : lies or cheats [for the SDQ for 2-4 year olds, replace 'lies' with 'argues']
bullied =Item 19 : picked on or bullied
helpout =Item 20 : often volunteers
reflect =Item 21 : thinks before acting
steals =Item 22 : steals [for the SDQ for 2-4 year olds, replace 'steals' with 'spite']
oldbest =Item 23 : better with adults than with children
afraid =Item 24 : many fears
attends =Item 25 : good attention
ebddiff =Impact question: oveall difficulties in at least one area
distres =Impact question: upset or distressed
imphome =Impact question: interferes with home life
impfrie =Impact question: interferes with friendships
impclas =Impact question: interferes with learning
impleis =Impact question: interferes with leisure

For each of these items, if the first response category (not true, no, not at all) has been selected, this is coded as zero, the next response category (somewhat true, yes-minor, just a little) is coded as one and so on.

For each informant, the algorithm generates six scores. The first letter of each derived variable is 'p' for parent-based scores, 's' for self-report-based scores and 't' for teacher-based scores. After this first letter, the names of the scores are as follows:

emotion =emotional symptoms
conduct =conduct problems
hyper =hyperactivity/inattention
peer =peer problems
prosoc =prosocial
ebdtot =total difficulties
impact =impact

# Syntax assumes data is already read into R

require(car) # Required for the "recode" function


# Recoding variables and then scoring the parent SDQ scores

qobeys <- recode (pobeys, "0=2; 1=1; 2=0; else=NA")
qreflect <- recode (preflect, "0=2; 1=1; 2=0; else=NA")
qattends <- recode (pattends, "0=2; 1=1; 2=0; else=NA")
qfriend <- recode (pfriend, "0=2; 1=1; 2=0; else=NA")
qpopular <- recode (ppopular, "0=2; 1=1; 2=0; else=NA")

qqdistres <- recode (pdistres, "0:1=0; 2=1; 3=2; NA=0")
qqimphome <- recode (pimphome, "0:1=0; 2=1; 3=2; NA=0")
qqimpfrie <- recode (pimpfrie, "0:1=0; 2=1; 3=2; NA=0")
qqimpclas <- recode (pimpclas, "0:1=0; 2=1; 3=2; NA=0")
qqimpleis <- recode (pimpleis, "0:1=0; 2=1; 3=2; NA=0")

df.pemotion <- data.frame(psomatic, pworries, punhappy, pclingy, pafraid)
pnemotion <- apply(df.pemotion, 1, function(x) sum(is.na(x)))
pemotion <- ifelse(pnemotion<3, rowMeans(df.pemotion, na.rm=TRUE), NA)
pemotion <- as.numeric(pemotion) * 5
pemotion <- floor(0.5 + pemotion)

df.pconduct <- data.frame(ptantrum, qobeys, pfights, plies, psteals)
pnconduct <- apply(df.pconduct, 1, function(x) sum(is.na(x)))
pconduct <- ifelse(pnconduct<3, rowMeans(df.pconduct, na.rm=TRUE), NA)
pconduct <- as.numeric(pconduct) * 5
pconduct <- floor(0.5 + pconduct)

df.phyper <- data.frame(prestles, pfidgety, pdistrac, qreflect, qattends)
pnhyper <- apply(df.phyper, 1, function(x) sum(is.na(x)))
phyper <- ifelse(pnhyper<3, rowMeans(df.phyper, na.rm=TRUE), NA)
phyper <- as.numeric(phyper) * 5
phyper <- floor(0.5 + phyper)

df.ppeer <- data.frame(ploner, qfriend, qpopular, pbullied, poldbest)
pnpeer <- apply(df.ppeer, 1, function(x) sum(is.na(x)))
ppeer <- ifelse(pnpeer<3, rowMeans(df.ppeer, na.rm=TRUE), NA)
ppeer <- as.numeric(ppeer) * 5
ppeer <- floor(0.5 + ppeer)

df.pprosoc <- data.frame(pconsid, pshares, pcaring, pkind, phelpout)
pnprosoc <- apply(df.pprosoc, 1, function(x) sum(is.na(x)))
pprosoc <- ifelse(pnprosoc<3, rowMeans(df.pprosoc, na.rm=TRUE), NA)
pprosoc <- as.numeric(pprosoc) * 5
pprosoc <- floor(0.5 + pprosoc)

df.pimpact <- data.frame(pdistres, pimphome, pimpfrie, pimpclas, pimpleis)
pnimpact <- apply(df.pimpact, 1, function(x) sum(is.na(x)))
pimpact <- ifelse(!pnimpact==5, qqdistres+qqimphome+qqimpfrie+qqimpclas+qqimpleis, NA)
pimpact <- ifelse(pebddiff==0, 0, pimpact)
pimpact <- as.numeric(pimpact)
pebdtot <- pemotion+pconduct+phyper+ppeer

rm(qobeys, qreflect, qattends, qfriend, qpopular, qqdistres, qqimphome, qqimpfrie, qqimpclas, qqimpleis, pnemotion, pnconduct, pnhyper, pnpeer, pnprosoc, pnimpact, df.pemotion, df.pconduct, df.phyper, df.ppeer, df.pprosoc, df.pimpact)

# Recoding variables and then scoring the youth self-report SDQ scores

robeys <- recode (sobeys, "0=2; 1=1; 2=0; else=NA")
rreflect <- recode (sreflect, "0=2; 1=1; 2=0; else=NA")
rattends <- recode (sattends, "0=2; 1=1; 2=0; else=NA")
rfriend <- recode (sfriend, "0=2; 1=1; 2=0; else=NA")
rpopular <- recode (spopular, "0=2; 1=1; 2=0; else=NA")

rrdistres <- recode (sdistres, "0:1=0; 2=1; 3=2; NA=0")
rrimphome <- recode (simphome, "0:1=0; 2=1; 3=2; NA=0")
rrimpfrie <- recode (simpfrie, "0:1=0; 2=1; 3=2; NA=0")
rrimpclas <- recode (simpclas, "0:1=0; 2=1; 3=2; NA=0")
rrimpleis <- recode (simpleis, "0:1=0; 2=1; 3=2; NA=0")

df.semotion <- data.frame(ssomatic, sworries, sunhappy, sclingy, safraid)
snemotion <- apply(df.semotion, 1, function(x) sum(is.na(x)))
semotion <- ifelse(snemotion<3, rowMeans(df.semotion, na.rm=TRUE), NA)
semotion <- as.numeric(semotion) * 5
semotion <- floor(0.5 + semotion)

df.sconduct <- data.frame(stantrum, robeys, sfights, slies, ssteals)
snconduct <- apply(df.sconduct, 1, function(x) sum(is.na(x)))
sconduct <- ifelse(snconduct<3, rowMeans(df.sconduct, na.rm=TRUE), NA)
sconduct <- as.numeric(sconduct) * 5
sconduct <- floor(0.5 + sconduct)

df.shyper <- data.frame(srestles, sfidgety, sdistrac, rreflect, rattends)
snhyper <- apply(df.shyper, 1, function(x) sum(is.na(x)))
shyper <- ifelse(snhyper<3, rowMeans(df.shyper, na.rm=TRUE), NA)
shyper <- as.numeric(shyper) * 5
shyper <- floor(0.5 + shyper)

df.speer <- data.frame(sloner, rfriend, rpopular, sbullied, soldbest)
snpeer <- apply(df.speer, 1, function(x) sum(is.na(x)))
speer <- ifelse(snpeer<3, rowMeans(df.speer, na.rm=TRUE), NA)
speer <- as.numeric(speer) * 5
speer <- floor(0.5 + speer)

df.sprosoc <- data.frame(sconsid, sshares, scaring, skind, shelpout)
snprosoc <- apply(df.sprosoc, 1, function(x) sum(is.na(x)))
sprosoc <- ifelse(snprosoc<3, rowMeans(df.sprosoc, na.rm=TRUE), NA)
sprosoc <- as.numeric(sprosoc) * 5
sprosoc <- floor(0.5 + sprosoc)

df.simpact <- data.frame(sdistres, simphome, simpfrie, simpclas, simpleis)
snimpact <- apply(df.simpact, 1, function(x) sum(is.na(x)))
simpact <- ifelse(!snimpact==5, rrdistres+rrimphome+rrimpfrie+rrimpclas+rrimpleis, NA)
simpact <- ifelse(sebddiff==0, 0, simpact)
simpact <- as.numeric(simpact)

sebdtot <- semotion+sconduct+shyper+speer

rm (robeys, rreflect, rattends, rfriend, rpopular, rrdistres, rrimphome, rrimpfrie, rrimpclas, rrimpleis, snemotion, snconduct, snhyper, snpeer, snprosoc, snimpact, df.semotion, df.sconduct, df.shyper, df.speer, df.sprosoc, df.simpact)

# Recoding variables and then scoring the teacher SDQ scores

uobeys <- recode (tobeys, "0=2; 1=1; 2=0; else=NA")
ureflect <- recode (treflect, "0=2; 1=1; 2=0; else=NA")
uattends <- recode (tattends, "0=2; 1=1; 2=0; else=NA")
ufriend <- recode (tfriend, "0=2; 1=1; 2=0; else=NA")
upopular <- recode (tpopular, "0=2; 1=1; 2=0; else=NA")

uudistres <- recode (tdistres, "0:1=0; 2=1; 3=2; NA=0")
uuimpfrie <- recode (timpfrie, "0:1=0; 2=1; 3=2; NA=0")
uuimpclas <- recode (timpclas, "0:1=0; 2=1; 3=2; NA=0")

df.temotion <- data.frame(tsomatic, tworries, tunhappy, tclingy, tafraid)
tnemotion <- apply(df.temotion, 1, function(x) sum(is.na(x)))
temotion <- ifelse(tnemotion<3, rowMeans(df.temotion, na.rm=TRUE), NA)
temotion <- as.numeric(temotion) * 5
temotion <- floor(0.5 + temotion)

df.tconduct <- data.frame(ttantrum, uobeys, tfights, tlies, tsteals)
tnconduct <- apply(df.tconduct, 1, function(x) sum(is.na(x)))
tconduct <- ifelse(tnconduct<3, rowMeans(df.tconduct, na.rm=TRUE), NA)
tconduct <- as.numeric(tconduct) * 5
tconduct <- floor(0.5 + tconduct)

df.thyper <- data.frame(trestles, tfidgety, tdistrac, ureflect, uattends)
tnhyper <- apply(df.thyper, 1, function(x) sum(is.na(x)))
thyper <- ifelse(tnhyper<3, rowMeans(df.thyper, na.rm=TRUE), NA)
thyper <- as.numeric(thyper) * 5
thyper <- floor(0.5 + thyper)

df.tpeer <- data.frame(tloner, ufriend, upopular, tbullied, toldbest)
tnpeer <- apply(df.tpeer, 1, function(x) sum(is.na(x)))
tpeer <- ifelse(tnpeer<3, rowMeans(df.tpeer, na.rm=TRUE), NA)
tpeer <- as.numeric(tpeer) * 5
tpeer <- floor(0.5 + tpeer)

df.tprosoc <- data.frame(tconsid, tshares, tcaring, tkind, thelpout)
tnprosoc <- apply(df.tprosoc, 1, function(x) sum(is.na(x)))
tprosoc <- ifelse(tnprosoc<3, rowMeans(df.tprosoc, na.rm=TRUE), NA)
tprosoc <- as.numeric(tprosoc) * 5
tprosoc <- floor(0.5 + tprosoc)

df.timpact <- data.frame(tdistres, timpfrie, timpclas)
tnimpact <- apply(df.timpact, 1, function(x) sum(is.na(x)))
timpact <- ifelse(!tnimpact==3, uudistres+uuimpfrie+uuimpclas, NA)
timpact <- ifelse(tebddiff==0, 0, timpact)
timpact <- as.numeric(timpact)

tebdtot <- temotion+tconduct+thyper+tpeer

rm (uobeys, ureflect, uattends, ufriend, upopular, uudistres, uuimpfrie, uuimpclas, tnemotion, tnconduct, tnhyper, tnpeer, tnprosoc, tnimpact, df.temotion, df.tconduct, df.thyper, df.tpeer, df.tprosoc, df.timpact)

The predictive algorithm was converted into R syntax by Tormod Bøe


Last modified : 08/10/14