2014-08-11 3 views
1

Я пытаюсь создать несколько графиков, используя ggplot2, которые затем собираются с использованием множителя. Однако, когда я пытаюсь создать X-графы, я получаю X одного и того же графа.Множитель ggplot2 с использованием переменных переменных

Мой код проблема в значительной степени сводится к тому, asuming df является dataframe

library(ggplot2) 

i = 1 
j = 2 
xVar = df[[i]] 
yVar = df[[j]] 
plot1 = ggplot(data = df, aes(xVar, yVar)) + geom_point(shape=1) 

i = 1 
j = 3 
xVar = df[[i]] 
yVar = df[[j]] 
plot2 = ggplot(data = df, aes(xVar, yVar)) + geom_point(shape=1) 

multiplot(plot1,plot2, cols=2) 

На данный момент Plot1 равно Plot2 и я не понимаю, почему.

Моего полный код, если интересно:

n = 1 
columns = colnames(df) 
plots = list() 

for(i in 3:7) 
{ 
    for(j in (i+1):7) 
    { 
     if(j < 8 & i < 7) { 
     xVar = df[[i]] 
     yVar = df[[j]] 

     plots[[n]] = ggplot(data = df, aes(x=xVar, y=yVar)) + 
       geom_point(shape=1) + 
       labs(x=columns[[i]], y=columns[[j]]) + 
       theme(axis.title=element_text(size=8)) 
     n = n + 1 
     } 
    } 
} 

multiplot(plotlist = plots, cols=3) 

ответ

3

Здесь многое происходит.

Во-первых, это действительно, на самом деле , действительно плохая идея использовать внешние переменные в вызовах aes(...). Аргументы aes(...) оцениваются в контексте аргумента data=..., поэтому в контексте df в вашем случае. Если это не удается, они оцениваются в глобальной среде. Поэтому крайне желательно, чтобы сделать что-то вроде этого:

gg <- data.frame(x=df[[i]],y=df[[j]]) 
plots[[n]] = ggplot(data = gg, aes(x,y)) +... 

Во-вторых, ggplot хранит выражения из aes(...) и оценивает их, когда сюжет оказывается (так, во время вызова multiplot(...)). На всех ваших участках используются переменные с именем xVar и yVar в aes(...). Поэтому, когда эти графики отображаются, ggplot использует все, что хранится в этих переменных в то время - предположительно, из последнего определения графика. Вот почему все ваши сюжеты выглядят как последние. Это ссылка на «ленивую оценку» в другом ответе.

С другой стороны, ggplot немедленно принимает аргумент data=... и сохраняет набор данных как часть определения графика (в gtable). Поэтому создание разных фреймов данных (например, gg выше), для каждого сюжета будет работать.

И, наконец, похоже, что вы пытаетесь создать парный сюжет (каждый столбец против каждого другого столбца, более или менее). Если это не домашнее задание, есть гораздо более простые способы сделать это.Вы можете использовать ggpairs(...) в GGally пакет (который использует сетку графика), или вы могли бы сделать это таким образом, используя основные ggplot с гранями:

# make up some data 
set.seed(1) # for reproducible example 
df <- data.frame(matrix(rnorm(700),nc=7)) 
df[4] <- 1+2*df[3] + rnorm(100) 
df[5] <- 3*df[3] - 2*df[4] + rnorm(100) 
df[6] <- -10*df[5] + rnorm(100) 

# you start here... 
gg.pairs <- function(data) { # scatterplot matrix using ggplot facets 
    require(ggplot2) 
    require(data.table) 
    require(reshape2) # for melt(...) 

    DT <- data.table(melt(cbind(id=1:nrow(data),data),id="id"),key="id") 
    gg <- DT[DT,allow.cartesian=T] 
    setnames(gg,c("id","H","x","V","y")) 
    ggplot(gg[as.integer(gg$H)<as.integer(gg$V),], aes(x,y)) + 
    geom_point(shape=1) + 
    facet_grid(V~H, scales="free") 
} 
gg.pairs(df[3:7]) 

+0

Это был действительно пары сюжет я пытался сделать и создание нового фреймворка данных, как вы предложили, работало. Тем не менее, мне оставалось задаться вопросом, существует ли эквивалент ключевого слова 'new', как на других языках, которые будут создавать экземпляр объекта? – KnightofniDK

2

Я думаю, что ваша проблема в R ленивых вычислений. В самом деле, что происходит в том, что plot1 и plot2 не создаются, когда вы назначаете его, но когда вы называете его, и в этот момент есть только одна копия (последний) из xVar и yVar и участки одинаковы

1

Ну, Я не могу объяснить, что происходит, но обходным путем является использование имен столбцов вместо столбцов с aes_string. Ниже приведены два уникальных графика в multiplot для меня, и это изменение может быть легко включено в ваш цикл графика.

dat = data.frame(x = rnorm(10), y1 = rnorm(10), y2 = rpois(10, 5)) 

xVar = names(dat)[1] 
yVar = names(dat)[2] 
plot1 = ggplot(data = dat, aes_string(xVar, yVar)) + geom_point(shape=1) 

yVar = names(dat)[3] 
plot2 = ggplot(data = dat, aes_string(xVar, yVar)) + geom_point(shape=1) 

multiplot(plot1, plot2, cols=2) 
Смежные вопросы