重新排列数据框以适应 R 中的纵向模型

Rearrange dataframe to fit longitudinal model in R

我有一个数据框,其中每个条目都与 NHS 中的职位发布相关,指定职位发布的周数,以及职位所在的 NHS Trust(和地区)。

目前我的数据框看起来像这样:

set.seed(1)
df1 <- data.frame(
  NHS_Trust = sample(1:30,20,T),
  Week = sample(1:10,20,T),
  Region = sample(1:15,20,T))

我想计算每个 NHS Trust 每周的工作数量,并将该值分配给新列 'jobs' 所以我的数据框如下所示:

set.seed(1)
df2 <- data.frame(
  NHS_Trust = rep(1:30, each=10),
  Week = rep(seq(1,10),30),
  Region = rep(as.integer(runif(30,1,15)),1,each = 10),
  Jobs = rpois(10*30, lambda = 2))

数据框然后可用于创建泊松纵向多级模型,我可以在其中对工作数量进行建模。

使用 data.table 包,您可以在单个表达式中分组、计数和分配给新列。 data.tables 的语法是 dt[i, j, by]。这里 i 是 "with" - 即 i 指定的数据子集或 i 顺序的数据,在这种情况下为空,因此所有数据都以其原始形式使用命令。 j 告诉要做什么,这里使用 .N 计算出现的次数,然后使用赋值运算符 := 将其分配给新变量 countby 获取变量列表,其中对每个组执行 j 操作。

library(data.table)
setDT(df1) 
df1[, count := .N, by = .(NHS_Trust, Week, Region)]

tidyverse 方法是

library(tidyverse)
df1 <- df1 %>% 
  group_by(NHS_Trust, Week, Region) %>% 
  count()

我想我正在将我的评论移至答案:

df2 <- df1 %>% group_by(Region, NHS_Trust, Week) %>% count(); colnames(df2)[4] <- "Jobs"

df2$combo <- paste0(df2$Region, "_", df2$NHS_Trust, "_", df2$Week)


for (i in 1:length(unique(df2$Region))){
  for (j in 1:length(unique(df2$NHS_Trust))){
    for (k in 1:length(unique(df2$Week))){

      curr_combo <- paste0(unique(df2$Region)[i], "_", 
                           unique(df2$NHS_Trust)[j], "_", 
                           unique(df2$Week)[k])

      if(!curr_combo %in% df2$combo){

        curdat <- data.frame(unique(df2$Region)[i], 
                             unique(df2$NHS_Trust)[j], 
                             unique(df2$Week)[k],
                             0,
                             curr_combo,
                             stringsAsFactors = FALSE)
        #cat(curdat)
        names(curdat) <- names(df2)
        df2 <- rbind(as.data.frame(df2), curdat)

      }
    }
  }
}

tail(df2)
#      Region NHS_Trust Week Jobs  combo
# 4495     15         1    4    0 15_1_4
# 4496     15         1    5    0 15_1_5
# 4497     15         1    8    0 15_1_8
# 4498     15         1    3    0 15_1_3
# 4499     15         1    6    0 15_1_6
# 4500     15         1    9    0 15_1_9

此处的 for loop 检查 df2 中缺少哪些 Region-NHS_Trust-Week 组合,并将这些组合附加到 df2 中,相应的 Jobs 值为 [=16] =].检查是在新变量 combo 的帮助下完成的,它只是前面提到的字段中的值的串联,用下划线分隔。

编辑:我很确定这里的人可以想出比这更优雅的东西。

您可以使用 count 计算每个 RegionNHS_TrustWeek 的职位数量,并使用 complete 填写缺失的组合。

library(dplyr)
df1 %>%
  count(Region, NHS_Trust, Week, name = 'Jobs') %>%
  tidyr::complete(Region, Week = 1:10, fill = list(Jobs = 0))