将大型数据帧子集化为变量列表的最佳方法?

时间:2013-08-11 02:54:58

标签: r dataframe subset

我目前有一个约83000行(13列)的数据框,其中包含2000 - 2012年犯罪数据,每行都是犯罪行为并且报告了邮政编码(所以邮政编码xxxxx可以在年份找到以2001年,2003年和2007年为例)。

以下是我的数据示例:

 Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL 
 2000       1 99502          1       3        5           2 9479           
 2009       2 99502          2       3        4           3 3220
 2000       1 11111          1       3        5           2 3479           
 2004       2 11111          2       3        4           3 1020

现在,我可以为我的所有邮政编码分配全局变量(我正在使用R studio,我显示的数据列表非常长,并且显着减慢了程序速度)。 以下是我为所有邮政编码分配全局变量的方法:

   for (n in all.data$Zip) {
     x <- subset(all.data, n == all.data$Zip) #subsets the data
     u <- x[1,3] #gets the zip code value
     assign(paste0("Zip", u), x, envir = .GlobalEnv)  #assigns it to a global environment
     #need something here, MasterList <<- ?

}  

我想在列表中包含所有这些变量。例如,如果我的所有邮政编码变量都存储在列表“MasterList”中:

   MasterList["Zip11111"]

将产生数据框:

 Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL 
 2000       1 11111          1       3        5           2 3479           
 2004       2 11111          2       3        4           3 1020

这可能吗?什么是替代/更快/更好的方法呢?我希望将这些变量存储在列表中会更有效。

奖励积分:我知道在我的for循环中,我将已经存在的变量重新分配给完全相同的东西,浪费处理时间。我可以添加任何快速线来加快速度吗?

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

您可以将for (n in all.data$Zip)更改为for (n in unique(all.data$Zip))。这将减少冗余。为什么不在循环之前列出一个列表MasterList <- list(),然后按

添加到列表中
MasterList[[paste0("Zip", n)]] <- x

是的,我使用n作为邮政编码,因为n分配了您告诉它的向量中的每个值(在您的情况下为all.data$Zip,在我的unique(all.data$Zip)中)

答案 1 :(得分:2)

制作列表的最简单方法可能就是使用plyr函数,如下所示:

> set.seed(2)
> dat <- data.frame(zip=as.factor(sample(11111:22222,1000,replace=T)),var1=rnorm(1000),var2=rnorm(1000))
> head(dat)
    zip       var1        var2
1 13165 -0.4597894 -0.84724423
2 18915  0.6179261  0.07042928
3 17481 -0.7204224  1.58119491
4 12978 -0.5835119  0.02059799
5 21598  0.2163245 -0.12337051
6 21594  1.2449912 -1.25737890
> library(plyr)
> MasterList <- dlply(dat,.(zip))
> MasterList[["13165"]]
    zip       var1       var2
1 13165 -0.4597894 -0.8472442

然而,听起来速度是你的动力,如果是这样的话,你可能会更好地不将数据存储在一些单独的列表对象中并将数据框转换为data.table()

> library(data.table)
> dat.dt <- data.table(dat)
> dat.dt[zip==13165]
     zip       var1       var2
1: 13165 -0.4597894 -0.8472442

答案 2 :(得分:2)

只有基数R:

 dat <- read.table(text = "Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL 
+  2000       1 99502          1       3        5           2 9479           
+  2009       2 99502          2       3        4           3 3220
+  2000       1 11111          1       3        5           2 3479           
+  2004       2 11111          2       3        4           3 1020",header = TRUE,sep = "")

> dats <- split(dat,dat$Zip)
> dats
$`11111`
  Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL
3 2000       1 11111          1       3        5           2 3479
4 2004       2 11111          2       3        4           3 1020

$`99502`
  Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL
1 2000       1 99502          1       3        5           2 9479
2 2009       2 99502          2       3        4           3 3220

> names(dats) <- paste0('Zip',names(dats))
> dats
$Zip11111
  Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL
3 2000       1 11111          1       3        5           2 3479
4 2004       2 11111          2       3        4           3 1020

$Zip99502
  Year Quarter   Zip MissingZip BusCode LossCode NumTheftsPQ  DUL
1 2000       1 99502          1       3        5           2 9479
2 2009       2 99502          2       3        4           3 3220