# Creating a composite variable with data that is missing by design

I have a dataset of 20 variables and over 2,000 observations. These variables are paired. A respondent is first asked if they endorse a goal. If they endorse that goal, a follow-up question asks how satisfied they are about perceived progress towards that goal. If they do not endorse the goal, then the second question is not asked, and that datum is missing. Consequently, the second of each paired question is unlikely to be missing at random. The first of the paired questions have a binary response. The second of the paired questions is ordinal, with five levels ranging from "very dissatisfied" to "very satisfied".

I would like to construct a composite variable (such as described here) describing satisfaction about perceived goal progress, among those goals that were endorsed. This variable is then regressed against a response variable of interest. There is no reason to think that satisfaction towards one goal is associated with satisfaction towards other goals - i.e. there is no reason to think that a common factor might drive responses - so using factor loadings wouldn't be appropriate. Similarly, the non-randomness of the pattern of missing data excludes inputting the missing values.

When designing the project, I planned to convert the ordinal variables into numeric, and simply take the mean of all those that were endorsed for each respondent. Of course, this assumes equal intervals between Likert-scale levels and equal contribution of each goal to aggregate satisfaction with goal progress.

A better approach might be to take into account differences in distance between response levels, and the relative importance of each goal towards the final response variable. I would be very grateful for ideas on how to do this? Below is a reproducible data frame:

# Number of rows and goals
set.seed(123) # set seed
n=1000
cols = 10

# DF indicating which respondents endorse which goals
DF1 <- data.frame(matrix(ncol=cols, nrow = n))
DF1 <- data.frame(apply(DF1, 2, function(x) round(runif(n,1,5),0)))
colnames(DF1) <- paste0(colnames(DF1), "_progress")

# Response
coefs <- rnorm(10,2,1)
y <- rowSums(DF1*coefs + rnorm(1000,0,1))

# Endorsement DF
DF2 <- data.frame(matrix(ncol =cols, nrow = n))
DF2 <- data.frame(apply(DF2, 2, function(x) rbinom(n,1,.8)))

# Full DF
Full_DF <- cbind(DF1, DF2)
Full_DF$response <- y # If a goal hasn't been endorsed, set progress to NA for (i in (1:10)){ DF1[,i] <- ifelse(DF2[,i] == 1, DF1[,i], NA) } # combine the DFs MISSING_DF <- cbind(DF1, DF2) MISSING_DF$response <- y


The less desired option is to simply take the mean progress towards endorsed goals, as below:

MISSING_DF\$means_progress <- rowMeans(MISSING_DF[,colnames(DF2)],na.rm =T)
summary(lm(response ~ means_progress, MISSING_DF))


I would be grateful for more sophisticated solutions!

• I am currently experiencing the same issues as stated above. I believe you may have discovered the best solution for the matter. Would you mind sharing? Thank you. – serene Apr 8 at 7:04