我有一个包含多个列的数据框,其中一个是一个名为“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
的图。
答案 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")
另一方面,我确实喜欢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)
每个情节都是如此。