创建不同长度的空数据框以存储for循环的结果

时间:2015-08-04 18:36:19

标签: r for-loop

我的数据集中有三个变量,如State,Year和Serotype。我下面的代码是聚合列出的数据。我创建了空数据帧来存储Agg.Res 1 2的for循环结果。依此类推。我的问题是如何制作空数据框以存储不同年份的结果?我想每年计算一次。当我运行此代码时,它只进行2013年的计算,因为我没有为data7创建空数据框来存储每年的结果。任何帮助将非常感激。

Agg.Res <- data.frame(matrix(NA, nrow=11, ncol=17)) 
for( i in 1:50 ){ # I am creating 50 sequentially numbered data frames
dataframe.name <- paste( "Agg.Res",i, sep="") # Names the matrix
assign( dataframe.name, Agg.Res, envir = .GlobalEnv) # Assigns template dataframe to name
}

#For State Illinois
data6<-data3[which(data3$State=="Illinois"),]

for(i in 2003:2013){  # loop for different years
data7<-data6[which(data6$YEAR==i),]

Ent1<-data7[which(data7$SEROTYPE_GR=="A"),]
Agg.Res1[i-2002,]<-colSums(Ent1[,31:47], na.rm=T)/nrow(Ent1)

Ent2<-data7[which(data7$SEROTYPE_GR=="B"),]
Agg.Res2[i-2002,]<-colSums(Ent2[,31:47], na.rm=T)/nrow(Ent2)

Ent3<-data7[which(data7$SEROTYPE_GR=="C"),]
Agg.Res3[i-2002,]<-colSums(Ent3[,31:47], na.rm=T)/nrow(Ent3)

Ent4<-data7[which(data7$SEROTYPE_GR=="D"),]
Agg.Res4[i-2002,]<-colSums(Ent4[,31:47], na.rm=T)/nrow(Ent4)

Ent5<-data7[which(data7$SEROTYPE_GR=="E"),]
Agg.Res5[i-2002,]<-colSums(Ent5[,31:47], na.rm=T)/nrow(Ent5)
}

数据如下所示:

State      Year          Serotype    Drug A    Drug B     Drug C . . . . 

Illinois   2003            A          1          0          1    . .. .  

Illinois   2003            B          0          0          1    . . . . 

 .          .              .           .          .          .    . . . 
 .          .              .           .          .          .    . . .
Missouri   2008            E           1          1          1  . . . . 

年份范围从2003年:2013年;血清型范围从A:E;还包括各种州。如果一种血清型对1给出的药物有抗药性,如果它不耐药则为0;二元变量。

1 个答案:

答案 0 :(得分:1)

看起来你做的工作比必要的要多得多。我建议使用data.table

library(data.table)
# I don't like using indices, but if you don't have column names, they'll have to do
dt_data <- as.data.table(data6[, c(1, 2, 31:47)])

# calculate column means by YEAR and SEROTYPE_GR. Resulting object is a data.table of the results
dt_colSumar <- dt_data[, lapply(.SD, mean), by = c("YEAR", "SEROTYPE_GR") ]

# split into list by SEROTYPE_GR
serotype_list <- split(dt_colSumar, dt_colSumar$SEROTYPE_GR)

# if you REALLY want to assign back to data frames
for (i in 1:5){
  assign(paste0("Agg.Res", i), as.data.frame(serotype_list[[i]]), envir = .GlobalEnv)
}