从宽到长重塑调查数据集

reshape survey data set from wide to long

我有这样一个调查数据集:

df <- data.frame(
  employment = 0.45,
  income = 0.3,
  incomeFU1 = 0.4,
  married = 0.1,
  employmentFU1 = 0.7,
  employmentFU2 = 0.8,
  incomeFU2 = 0.8,
  smokingFU1 = 0.6,
  smokingFU3 = 0.1,
  ageFU3 = 0.9,
  marriedFU2 = 0.3
)

在这个数据集中,个人被问及他们的就业状况、收入等。 数据是一个综合水平,将其视为就业人口的比例,平均收入等。因此数据集只有一行。

本次调查中的个人在基线和 3 次跟进时被问及。 基线变量没有结尾字符串,后续答案的结尾类似于 "FU1" 后续 1 等等。

我现在有了这些变量的第二个列表:

l <- list()
l[[1]] <- c("employment", "income", "married")
l[[2]] <- c("employmentFU1", "incomeFU1", "smokingFU1")
l[[3]] <- c("employmentFU2", "incomeFU2", "marriedFU2")
l[[4]] <- c("smokingFU3", "ageFU3")

第一个列表项有基线变量,第二个列表项有后续 1 个变量,第三个有后续 2 等

请注意,一些变量在 2 次或 3 次(有时甚至全部)后续行动中可用,有些只出现一次。

我现在想根据列表变量将此数据框重塑为矩阵或数据框,如下所示:

employment      income         married              NA          NA
employmentFU1   incomeFU1           NA      smokingFU1          NA
employmentFU2   incomeFU2   marriedFU2              NA          NA
           NA          NA           NA      smokingFU3      ageFU3

这个矩阵中的行数是列表元素的数量,在本例中是 4。

我试过这样的东西,但没有走得太远:

m <- matrix()
m[1,1] <- df[, l[[1]][1]]
m[1,2] <- l[[2]][str_detect(l[[1]][1], l[[2]])]

这就是我尝试使用 stringr 解决该问题的方法。可能存在更有效的方法

library(stringr)
table <- str_match(unlist(l), "(.*?)($|FU[0-9]+?)")
table[table==""] <- "FU0" ## "" is problematic

m <- matrix(NA, length(unique(table[,3])), length(unique(table[,2])))
colnames(m) <- unique(table[,2])
rownames(m) <- unique(table[,3])

foo <- apply(table, 1, function(row) m[row[3],row[2]] <<- row[1])

print(m)
#    employment      income      married      smoking      age
#FU0 "employment"    "income"    "married"    NA           NA
#FU1 "employmentFU1" "incomeFU1" NA           "smokingFU1" NA
#FU2 "employmentFU2" "incomeFU2" "marriedFU2" NA           NA
#FU3 NA              NA          NA           "smokingFU3" "ageFU3"