如何按行拆分数据框,然后处理块?

时间:2009-09-08 17:22:51

标签: r split dataframe

我有一个包含多个列的数据框,其中一个是一个名为“site”的因子。如何将数据框拆分为每个具有唯一值“site”的行块,然后使用函数处理每个块?数据如下所示:

site year peak
ALBEN 5 101529.6
ALBEN 10 117483.4
ALBEN 20 132960.9
ALBEN 50 153251.2
ALBEN 100 168647.8
ALBEN 200 184153.6
ALBEN 500 204866.5
ALDER 5 6561.3
ALDER 10 7897.1
ALDER 20 9208.1
ALDER 50 10949.3
ALDER 100 12287.6
ALDER 200 13650.2
ALDER 500 15493.6
AMERI 5 43656.5
AMERI 10 51475.3
AMERI 20 58854.4
AMERI 50 68233.3
AMERI 100 75135.9
AMERI 200 81908.3

我希望为每个网站创建year vs peak的图。

7 个答案:

答案 0 :(得分:14)

您可以使用isplit(来自“iterators”包)创建迭代器对象,该对象循环遍历site列定义的块:

require(iterators)
site.data <- read.table("isplit-data.txt",header=T) 
sites <- isplit(site.data,site.data$site)

然后你可以使用foreach(来自“foreach”包)在每个块中创建一个图:

require(foreach)
foreach(site=sites) %dopar% {
 pdf(paste(site$key[[1]],".pdf",sep=""))
 plot(site$value$year,site$value$peak,main=site$key[[1]])
 dev.off()
}

作为奖励,如果您有一台多处理器机器并首先调用registerDoMC()(来自“doMC”软件包),则循环将并行运行,从而加快速度。本革命博客文章中的更多细节:Block-processing a data frame with isplit

答案 1 :(得分:12)

另一种选择是使用ddply库中的ggplot2函数。但是你提到你大多想要做一个高峰与年份的情节,所以你也可以使用qplot

A <- read.table("example.txt",header=TRUE)
library(ggplot2)
qplot(peak,year,data=A,colour=site,geom="line",group=site)
ggsave("peak-year-comparison.png")

alt text

另一方面,我确实喜欢David Smith的解决方案,该解决方案允许将函数应用于多个处理器。

答案 2 :(得分:10)

我似乎记得简单的旧split()有一个data.frames方法,因此split(data,data$site)会产生一个块列表。然后,您可以使用sapply / lapply / for对此列表进行操作。

由于split()

unsplit()也很不错,它会创建一个与原始数据长度相同的矢量,并且顺序正确。

答案 3 :(得分:6)

这就是我要做的事情,虽然你们看起来好像是由图书馆功能处理的。

for(i in 1:length(unique(data$site))){
  constrainedData = data[data$site==data$site[i]];
  doSomething(constrainedData);
}

这种代码更直接,效率可能更低,但我更愿意阅读它正在做的事情,而不是为同一件事学习一些新的库函数。让这种感觉更加灵活,但老实说,这就是我作为一个新手想出来的方式。

答案 4 :(得分:4)

有两种方便的内置函数可以处理这种情况。 ?聚合和?by。在这种情况下,因为你想要一个绘图并且没有返回一个标量,所以使用by()

data <- read.table("example.txt",header=TRUE)

by(data[, c('year', 'peak')], data$site, plot)

输出显示NULL,因为这是情节返回的。您可能希望将图形设备设置为pdf以捕获所有输出。

答案 5 :(得分:2)

使用晶格包生成图也很容易:

library(lattice)
xyplot(year~peak | site, data)

答案 6 :(得分:0)

您可以使用split功能 如果您将数据打开为:

data <- read.table('your_data.txt', header=T)
blocks <- split(data, data$site)

之后,块包含来自每个块的数据,您可以访问其他data.frame:

plot(blocks$ALBEN$year, blocks$ALBEN$peak)

每个情节都是如此。