2016-11-06 8 views
-1

私は一連の被験者に対する一連の薬物による治療の結果が一連の病院で測定されたデータを持っています。 (#drugs> #subjects> #hospitals)マトリックスを効率的に充填する

マイdata.frameは、各行ごとにdrugsubjecthospitaloutcome組み合わせてい

subjects <- paste("S",1:100,sep="_") 
drugs <- paste("D",1:1000,sep="_") 

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それぞれを構築したいが行はユニークなhospitalsubjectの組み合わせであり、各列は固有のhospitaldrugの組み合わせです。ここでは、おそらくこの行列を構築するためのない最適に効率的な方法です:

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がより効率的にこれが可能である場合は、この行列を構築する方法です。今

、マトリックスは、私はこれらのsubjectsがから、それらが観察されたhospital.drugの組み合わせに応じて、観察されなかった中で、すなわち、そのhospital.drug組み合わせて、欠損値と各hospital.subject組み合わせを転嫁したいのですが希薄であるため、 mean = medianおよびsd = madのこれらの観察されたhospital.subject組み合わせの正規分布。すなわち

は、hospitals[1]のみで観察されたsubjects[1:10]、たとえばため、各drugためhospitals[1]からhospitals[2:10]ために埋めます。それは意味:

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]))

ので、1と次病院(マット内の行)のために、例えば、forループを使用して

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(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]])) 
    } 
} 

これを達成するためのより効率的でエレガントな方法がありますか?

私の実際のデータは、各病院の被験者の数が同一ではないという意味でこの例よりも組織化されておらず、さらに複数の病院で同じ薬剤で治療されている被験者。

答えて

2

これは何ですか?

df$hos.sub=paste(df$hospital,df$subject) 
df$hos.dru=paste(df$hospital,df$drug) 

ind1 <- list(factor(df$hos.sub),factor(df$hos.dru)) 
res<-tapply(df[,"outcome"],ind1,mean) 
head(res[,1:10]) 

> head(res[,1:9]) 
      H_1 D_1 H_1 D_10 H_1 D_100 H_1 D_1000 H_1 D_101 H_1 D_102 H_1 D_103 H_1 D_104 H_1 D_105 
H_1 S_1 26.550866 83.189899 6.516364 45.77171 6.471249 26.6257392 81.14044 9.088058 67.64499 
H_1 S_10 6.178627 4.288589 45.675309 77.90078 3.338293 95.5751769 92.02642 49.810641 14.31814 
H_1 S_2 37.212390 76.684275 27.743618 21.32599 67.661240 66.0476814 82.46891 97.271288 88.86986 
H_1 S_3 57.285336 27.278032 60.041069 55.22206 73.537169 21.2416518 91.60083 85.267414 95.01507 
H_1 S_4 90.820779 18.816330 27.314448 13.21052 11.129967 0.5266102 72.34151 49.899330 91.69972 
H_1 S_5 20.168193 22.576183 94.148905 44.60504 4.665462 10.2902506 91.02545 27.440370 90.51900 
+0

私は私の質問で記述している方法を教えているとは思わない – dan