我有一组数据,其中一套药物对一组受试者的治疗结果在一组医院内进行了测量。 (#drugs> #subjects> #hospitals)有效填充基质
subjects <- paste("S",1:100,sep="_")
drugs <- paste("D",1:1000,sep="_")
我data.frame
在每个每一行drug
,subject
,hospital
,outcome
组合:
df <- expand.grid(subject=subjects,drug=drugs,stringsAsFactors=F)
hospitals <- paste("H",1:10,sep="_")
df$hospital <- rep(sapply(hospitals,function(h) rep(h,10)),200)
set.seed(1)
df$outcome <- runif(nrow(df),0,100)
现在我想建立一个matrix
其中每个排是独特的hospital
subject
组合,每一列是独特的hospital
drug
组合。这里有可能建立这个矩阵不能很好有效的方法:
df$hospital.subject <- paste(df$hospital,df$subject,sep=":")
df$hospital.drug <- paste(df$hospital,df$drug,sep=":")
hospital.subject <- unique(paste(df$hospital,df$subject,sep=":"))
hospital.drug <- unique(paste(df$hospital,df$drug,sep=":"))
mat <- do.call(rbind,lapply(hospital.subject, function(x){
hospital.subject.df <- dplyr::filter(df,hospital.subject==x)
res <- rep(NA,length(hospital.drug))
match.idx <- match(hospital.drug,hospital.subject.df$hospital.drug)
res[which(!is.na(match.idx))] <- hospital.subject.df$outcome[match.idx[which(!is.na(match.idx))]]
return(res)
}))
rownames(mat) <- hospital.subject
colnames(mat) <- hospital.drug
所以问题#1是如何更有效地这是否可能建立这个矩阵。现在
,由于矩阵是稀疏矩阵我想插补各hospital.subject
组合在其hospital.drug
组合,即,其中没有观察到这些subjects
缺失值,根据它们被观察到的hospital.drug
组合,从正态分布与mean
= median
和sd
= mad
这些观察到的hospital.subject
组合。
换句话说,例如用于subjects[1:10]
,将其仅在hospitals[1]
观察到的,从hospitals[1]
填写为hospitals[2:10]
对于每个相应drug
。这意味着:
mat[1:10,2:10] <- rnorm(90,median(mat[1:10,1]),mad(mat[1:10,1]))
mat[1:10,12:20] <- rnorm(90,median(mat[1:10,1]),mad(mat[1:10,1]))
等一个和下一个医院(在垫子行),例如,
mat[31:40,2:10] <- rnorm(90,median(mat[31:40,1]),mad(mat[31:40,1]))
mat[31:40,12:20] <- rnorm(90,median(mat[31:40,1]),mad(mat[31:40,1]))
使用for
循环我会这样做:
for(h in 1:length(hospitals)){
row.idx <- which(grepl(paste0(hospitals[h],":"),hospital.subject)==T)
col.idx <- which(grepl(paste0(hospitals[h],":"),hospital.drug)==T)
for(i in 1:length(col.idx)){
drug <- strsplit(hospital.drug[col.idx[i]],split=":")[[1]][2]
impute.idx <- which(grepl(paste0(":",drug,"$"),hospital.drug,perl=T)==T)[-col.idx[i]]
mat[row.idx,impute.idx] <- rnorm(length(row.idx)*length(impute.idx),mean=median(mat[row.idx,col.idx[i]]),sd=mad(mat[row.idx,col.idx[i]]))
}
}
有没有更高效和更优雅的方法来实现这个目标?
还有一点,我的实际数据组织得比这个例子好,因为每个医院的受试者人数并不相同,另外还有一个以上的医院使用同一种药物治疗的受试者。
我不认为这是在我的问题中描述的方式推算 – dan