我有两个数据帧,Tg和Pf,每列127列。所有列至少有一行,最多可包含数千行。所有值都在0到1之间,并且存在一些缺失值(空单元格)。这是一个小子集:
Tg
Tg1 Tg2 Tg3 ... Tg127
0.9 0.5 0.4 0
0.9 0.3 0.6 0
0.4 0.6 0.6 0.3
0.1 0.7 0.6 0.4
0.1 0.8
0.3 0.9
0.9
0.6
0.1
Pf
Pf1 Pf2 Pf3 ...Pf127
0.9 0.5 0.4 1
0.9 0.3 0.6 0.8
0.6 0.6 0.6 0.7
0.4 0.7 0.6 0.5
0.1 0.6 0.5
0.3
0.3
0.3
请注意,某些单元格为空,同一子集(即1到127)的向量长度可能具有非常不同的长度,并且很少具有相同的精确长度。 我想为127个向量生成如下图127(即图表是每个数据帧的第1列,图2是每个数据帧的第2列等):
希望这是有道理的。我期待着您的帮助,因为我不想一个一个地制作这些图表...... 谢谢!
答案 0 :(得分:4)
以下是一个让您入门的示例(https://gist.github.com/1349300处的数据)。如需进一步调整,请查看网络上的优秀ggplot2
文档。
library(ggplot2)
# Load data
Tg = read.table('Tg.txt', header=T, fill=T, sep=' ')
Pf = read.table('Pf.txt', header=T, fill=T, sep=' ')
# Format data
Tg$x = as.numeric(rownames(Tg))
Tg = melt(Tg, id.vars='x')
Tg$source = 'Tg'
Tg$variable = factor(as.numeric(gsub('Tg(.+)', '\\1', Tg$variable)))
Pf$x = as.numeric(rownames(Pf))
Pf = melt(Pf, id.vars='x')
Pf$source = 'Pf'
Pf$variable = factor(as.numeric(gsub('Pf(.+)', '\\1', Pf$variable)))
# Stack data
data = rbind(Tg, Pf)
# Plot
dev.new(width=5, height=4)
p = ggplot(data=data, aes(x=x)) + geom_line(aes(y=value, group=source, color=source)) + facet_wrap(~variable)
p
突出显示行之间的区域
首先,将数据内插到更精细的网格上。这样,功能区将遵循线的实际包络,而不是原始数据点所在的位置。
data = ddply(data, c('variable', 'source'), function(x) data.frame(approx(x$x, x$value, xout=seq(min(x$x), max(x$x), length.out=100))))
names(data)[4] = 'value'
接下来,计算geom_ribbon
所需的数据 - 即ymax
和ymin
。
ribbon.data = ddply(data, c('variable', 'x'), summarize, ymin=min(value), ymax=max(value))
现在是时候绘制了。请注意我们是如何添加新的功能区图层的,我们已为其替换了新的ribbon.data
框架。
dev.new(width=5, height=4)
p + geom_ribbon(aes(ymin=ymin, ymax=ymax), alpha=0.3, data=ribbon.data)
行之间的动态着色
最棘手的变化是,如果您希望着色根据数据而变化。为此,您当前必须创建一个新的分组变量来标识不同的分段。例如,在这里,我们可能会使用一个函数来指示" Tg"小组名列前茅:
GetSegs <- function(x) {
segs = x[x$source=='Tg', ]$value > x[x$source=='Pf', ]$value
segs.rle = rle(segs)
on.top = ifelse(segs, 'Tg', 'Pf')
on.top[is.na(on.top)] = 'Tg'
group = rep.int(1:length(segs.rle$lengths), times=segs.rle$lengths)
group[is.na(segs)] = NA
data.frame(x=unique(x$x), group, on.top)
}
现在我们应用它并将结果与我们原始的功能区数据合并。
groups = ddply(data, 'variable', GetSegs)
ribbon.data = join(ribbon.data, groups)
对于情节,关键是我们现在为功能区geom指定分组审美。
dev.new(width=5, height=4)
p + geom_ribbon(aes(ymin=ymin, ymax=ymax, group=group, fill=on.top), alpha=0.3, data=ribbon.data)
代码可在以下网址获得:https://gist.github.com/1349300
答案 1 :(得分:2)
这是一个三线做同样的事:-)。我们首先从reshape
base
将数据转换为长格式。然后,它融化以适应ggplot2
。最后,我们生成情节!
mydf <- reshape(cbind(Tg, Pf), varying = 1:8, direction = 'long', sep = "")
mydf_m <- melt(mydf, id.var = c(1, 4), variable = 'source')
qplot(id, value, colour = source, data = mydf_m, geom = 'line') +
facet_wrap(~ time, ncol = 2)
请注意。 reshape
R中的base
函数非常强大,尽管使用起来非常混乱。它用于在long
和wide
格式之间转换数据。
答案 2 :(得分:1)
使用R自动执行您以前在Excel中执行的操作的荣誉!这正是我开始使用R和R启蒙的共同路径的方式:)
你真正需要的只是一个小循环。这是一个示例,其中大部分是创建表示数据结构的示例数据:
## create some example data
Tg <- data.frame(Tg1 = rnorm(10))
for (i in 2:10) {
vec <- rep(NA, 8)
vec <- c(rnorm(sample(5:10,1)), vec)
Tg[paste("Tg", i, sep="")] <- vec[1:10]
}
Pf <- data.frame(Pf1 = rnorm(10))
for (i in 2:10) {
vec <- rep(NA, 8)
vec <- c(rnorm(sample(5:10,1)), vec)
Pf[paste("Pf", i, sep="")] <- vec[1:10]
}
## ok, sample data created
## now lets loop through all the columns
## if you didn't know how many columns there are you could
## use ncol(Tg) to figure out
for (i in 1:10) {
plot(1:10, Tg[,i], type = "l", col="blue", lwd=5, ylim=c(-3,3),
xlim=c(1, max(length(na.omit(Tg[,i])), length(na.omit(Pf[,i])))))
lines(1:10, Pf[,i], type = "l", col="red", lwd=5, ylim=c(-3,3))
dev.copy(png, paste('rplot', i, '.png', sep=""))
dev.off()
}
这将导致工作目录中的10个图形如下所示: