Накопление адаптированных объектов графика ggpairs () в объект списка

Я пытаюсь создать объект списка, содержащий графики GGally. Каждый из этих графиков создается с двумя наборами данных, основным набором данных и подмножеством основного набора данных, которые снова отображаются оранжевым цветом. В MWE ниже созданы три графика, каждый из которых сравнивает два столбца из данных mtcars и каждый содержит разное количество точек подмножества, которые должны быть нанесены оранжевым цветом:

График_1: миль на галлон и цил, 1 точка с наложением оранжевого цвета

Сюжет_2: миль на галлон и расход, 20 оранжевых точек с наложением

Участок_3: мили на галлон и л.с., 30 оранжевых точек наложены

library(GGally)
library(ggplot2)

data = mtcars
data$ID = rownames(mtcars)
data = data[, c(12,1:11)]

  my_fn <- function(data, mapping, ...){
    xChar = as.character(mapping$x)
    yChar = as.character(mapping$y)
    x = data[,c(xChar)]
    y = data[,c(yChar)]
    p <- ggplot(data, aes(x=x, y=y)) + geom_point() + geom_point(data = colorData, aes_string(x=xChar, y=yChar), inherit.aes = FALSE)
    p
  }

  ret=list()
  colorVec = c(1, 10, 20)
  k=1
    for (j in c(3:5)){
      datSel <- cbind(ID=data$ID, data[,c(2, j)])
      datSel$ID = as.character(datSel$ID)
      colorData <- datSel[sample(1:nrow(data), colorVec[k]),]
      p <- ggpairs(datSel[,-1], lower = list(continuous = my_fn), upper = list(continuous = wrap("cor", size = 4))) + theme_gray()
      ret[[paste0("Plot_",j)]] <- p
      k=k+1
    }  

Однако, когда я запускаю этот код и создаю объект списка ret, только последний объект графика в списке успешно создает график. Первые два объекта списка не могут найти один из столбцов в данных.

> ret[["Plot_1"]]
Error in FUN(X[[i]], ...) : object 'cyl' not found

> ret[["Plot_2"]]
Error in FUN(X[[i]], ...) : object 'disp' not found

> ret[["Plot_3"]]
Correctly plotted

Как можно безболезненно решить эту проблему? Заранее благодарю вас за совет.

РЕДАКТИРОВАТЬ:

Добавление информации о сеансе для воспроизводимости

> sessionInfo()
R version 3.4.3 (2017-11-30)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Sierra 10.12.6

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_2.2.1 GGally_1.3.2 

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.15       reshape_0.8.7      grid_3.4.3         plyr_1.8.4         gtable_0.2.0      
 [6] magrittr_1.5       scales_0.5.0       pillar_1.2.1       stringi_1.1.6      rlang_0.2.0       
[11] reshape2_1.4.3     lazyeval_0.2.1     labeling_0.3       RColorBrewer_1.1-2 tools_3.4.3       
[16] stringr_1.3.0      munsell_0.4.3      yaml_2.1.17        compiler_3.4.3     colorspace_1.3-2  
[21] tibble_1.4.2

person Community    schedule 24.03.2018    source источник
comment
Что произойдет, если вы используете в своем коде ret [[j]] ‹- p вместо того, что у вас есть сейчас? Затем попробуйте ret [[1]], ret [[2]] и т. Д., Чтобы получить доступ к первому, второму и т. Д. Графику? Вы можете назначить имена своему объекту ret с помощью команды names () после того, как закончите сохранять в нем все графики.   -  person Isabella Ghement    schedule 25.03.2018
comment
Спасибо @IsabellaGhement. Этот подход, кажется, приводит к тем же результатам, когда я делаю ret [[3]], ret [[4]] и ret [[5]] (поскольку j находится между 3 и 5).   -  person    schedule 25.03.2018
comment
Я думаю, это потому, что ваш j работает от 3 до 5? Так что, возможно, объявите свой ret как ret ‹- vector (list, 3) перед тем, как вы войдете в цикл for, а затем внутри цикла, что-то вроде этого: ret [[j - 2]]‹ - p. Затем ret [[1]] должен сохранять график для j = 3, ret [[2]] должен сохранять график для j = 4 и т. Д.   -  person Isabella Ghement    schedule 25.03.2018
comment
@IsabellaGhement. Спасибо, но это также приводит к той же проблеме: когда я делаю ret [[1]], я получаю сообщение об ошибке, что объект «цил» не найден, когда я делаю ret [[2]], я получаю сообщение об ошибке объект disp не найден, и когда я делаю ret [[3]], я получаю успешный вывод графика.   -  person    schedule 25.03.2018
comment
Ваш код не воспроизводится. Когда я побежал, то получил ошибку: Error in make_ggmatrix_plot_obj(wrapp(sub_type, funcArgName = sub_type_name), : variables: "x" have non standard format: "~mpg". Please rename the columns or make a new column.   -  person Tung    schedule 25.03.2018
comment
Спасибо, что сообщили мне, @Tung. Я просто закрыл R и перезапустил его, и, похоже, у меня это сработало. Как вы думаете, это могут быть разные версии R и пакетов? Я добавил информацию о сеансе в качестве правки в свой исходный пост на случай, если это вызовет различия.   -  person    schedule 25.03.2018
comment
Не работает у меня после перезапуска сеанса R. Я использую последнюю разрабатываемую версию ggplot2_2.2.1.9000 & GGally_1.3.2 в Microsoft R Open 3.4.3   -  person Tung    schedule 25.03.2018
comment
Кажется, у вас проблемы с созданием сюжета, а не с его хранением. Вы можете использовать print (p) прямо перед сохранением графика, а также использовать параметры (warn = 2) перед запуском кода, чтобы заставить R остановиться, если он обнаружит ошибку.   -  person Isabella Ghement    schedule 25.03.2018
comment
@ Тунг, спасибо, что дали мне знать. Интересно, связано ли это с тем, что мы используем разные версии ggplot2 или разные операционные системы (я использую Mac). @IsabellaGhement результаты остались прежними. Интересно, появляется ли у вас то же сообщение об ошибке, что и у Тунга? Спасибо еще раз.   -  person    schedule 25.03.2018


Ответы (1)


Возможное решение, если я правильно понял ваш вопрос:

library(GGally)
data = mtcars
data$ID = rownames(mtcars)
data = data[, c(12,1:11)]

# Load tidyverse
library(tidyverse)

# Create a vector list for each plot you want
var_list <- data.frame(var = names(data)[3:5], 
                   color = colorVec)

# Function for sampling orange points
my_color_fn <- function(data, color_nb) {
  sample(1:nrow(data), color_nb)
}

# Create a list with a data for each variable with colors
data_list <- apply(var_list, 1, 
                   function(x) 
                     data %>% 
                      select(ID, mpg, as.character(x[["var"]])) %>% 
                      mutate(color = "black") %>% 
                      mutate(color = replace(color, my_color_fn(., x[["color"]]), "orange")))

# Update my_fn function
my_fn <- function(data, mapping, ...){
  xChar = as.character(mapping$x)
  yChar = as.character(mapping$y)
  x = data[, c(xChar)]
  y = data[, c(yChar)]
  p <- ggplot(data, aes_string(x=x, y=y)) + 
    geom_point(aes(color = color)) + 
    scale_color_manual("", values = c("black" = "black",
                                      "orange" = "orange"))
  p
}

# Create a function to get ggpairs for each subset
my_fn2 <- function(data)
{
  p <- ggpairs(data %>% select(- ID), 1:2, 
               lower = list(continuous = my_fn), 
               upper = list(continuous = wrap("cor", size = 4)))
  return(p)
}

# Get plot for each list element
ret <- lapply(data_list, function(x) my_fn2(x))

ret[[1]]
ret[[2]]
ret[[3]]

plot_1  plot_2 plot_3

person bVa    schedule 27.03.2018