Как создать линейный график с группами в Base R без циклов?
Мне нужно создать простой график линии с группами, используя следующие данные:
test = data.frame(x = rep(1:3, each = 2),
group = rep(c("Group 1","Group 2"),3),
groupcd= rep(c(1,2),3),
y= c(22,8,11,4,7,5)
)
Я легко могу сделать это с помощью GGPLOT:
library(ggplot2)
#GGPLOT
qplot(x=x, y=y,
data=test,
colour=group,
main="GGPLOT line plot with groups") +
geom_line()
![enter image description here]()
Я также могу сделать это с помощью TRELLIS:
library(lattice)
xyplot(y~x,
type="b",
group=group,
data=test,
main="TRELLIS line plot with groups",
auto.key =list(
lines = TRUE)
)
![enter image description here]()
Однако, я немного неохотно использую GGPLOT или TRELLIS прямо сейчас. Я хотел бы иметь возможность создать этот график с базой R. Единственный способ, которым я могу получить этот график для работы в Base R, - это использовать для цикла:
# set up empty plot
plot(test$y ~test$x, ylab="y", xlab="x", type="n", main="Base R line plot with groups")
colors<-c("red","blue")
#plot each group in the for loop
number_of_groups <- as.numeric(max(unique(test$groupcd))) #calculate number of groups
for (i in 1:number_of_groups)
{
temp <- subset(test, groupcd==i )
lines(temp$x, temp$y, col=colors[i])
points(temp$x, temp$y, col=colors[i])
}
legend("top", legend=unique(test$group), text.col =colors )
![enter image description here]()
Этот подход кажется довольно запутанным. Есть ли более простой способ сделать это в базе R? Есть ли опция группы в базовой функции R-графика? Большое вам спасибо.
Ответы
Ответ 1
Что-то вроде этого в качестве основы для работы от:
test = data.frame(x = rep(1:3, each = 2),
group = rep(c("Group 1","Group 2"),3),
groupcd= rep(c(1,2),3),
y= c(22,8,11,4,7,5)
)
xvals <- split(test$x,test$group)
yvals <- split(test$y,test$group)
plot(1:max(unlist(xvals)),ylim=(c(0,max(unlist(yvals)))),type="n")
# thanks to @BenBolker for refining this next key line
mapply(lines,xvals,yvals,col=c("red","blue"),pch=1:2,type="o")
Результат:
![enter image description here]()
Ответ 2
Разный подход с использованием MATPLOT:
library(reshape)
test = data.frame(x = rep(1:3, each = 2),
group = rep(c("Group 1","Group 2"),3),
groupcd= rep(c(1,2),3),
y= c(22,8,11,4,7,5)
)
colors<-c("red","blue")
#Transform data to wide format
test_transposed<-reshape(test,
idvar='x',
drop="group",
timevar="groupcd",
direction="wide")
colors<-c("red","blue")
#drop x column
test_transposed$x<-NULL
matplot(test_transposed,
type = "b",
ylab="y",
col=colors,
main="MATPLOT with groups",
pch = 1:2)
legend("top",
legend=unique(test$group),
lty=1:2,
col=colors,
pch=1:2 )
![enter image description here]()
Ответ 3
Мне тоже было интересно. Мои данные панели не имеют полного охвата по оси x (годы), поэтому матричные решения, вероятно, станут сложными. Вместо этого я пошел с...
mytest = data.frame(
x = rep(1:3, each = 2),
groupcd= rep(c(1,2),3),
y= c(22,8,11,4,7,5)
)
mytest = rbind(mytest,c(2,3,15),c(3,3,17))
plottables <- split(mytest,mytest$groupcd)
plot(y~x,dat=plottables[[1]],type="l",xlim=range(mytest$x),ylim=range(mytest$y))
lapply(plottables,function(z)points(y~x,dat=z,type="l"))
Ответ 4
Я хотел бы немного расширить этот пост. Предположим, что инсталляция линий строчки мне нужна линиями регрессии. Расширение кода @Frank..
mytest = data.frame(
x = rep(1:3, each = 2),
groupcd= rep(c(1,2),3),
y= c(22,8,11,4,7,5)
)
mytest = rbind(mytest,c(2,3,15),c(3,3,17))
plottables <- split(mytest,mytest$groupcd)
plot(y~x,dat=plottables[[1]],type="n",xlim=range(mytest$x),ylim=range(mytest$y))
lapply(plottables,function(z)points(z$x, z$y))
lapply(plottables,function(z)lines(z$x, predict(lm(z$y ~ z$x), list(z$x))))
Теперь предположим, что я также хочу, чтобы цвета изменялись для каждого уровня группы.
Я пробовал подход, предложенный @BenBolker
xvals <- tapply(mytest$x, mytest$groupcd, function(x) return(x))
yvals <- tapply(mytest$y, mytest$groupcd, function(x) return(x))
plot(1:max(unlist(xvals)),ylim=(c(0,max(unlist(yvals)))),type="n")
mapply(points, xvals, yvals, bg=c(1:3),pch=21,type="p")
mapply(lines(xvals, predict(lm(yvals ~ xvals), list(xvals)), col = c(1:3)))
но не работает.