2017-01-19 3 views
11

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

В приведенном ниже примере каждый [email protected] представляет собой структуру int [] со 100 значениями. В общей сложности он создается 10 раз в my_fn (один раз для каждого из 10 нижних левых недиагональных подзаглавов). Я пытаюсь сохранить все 10 из этих структур [email protected] в объекте списка listCID.

У меня не было успеха в этом подходе, и я попробовал несколько других вариантов (например, попытку поставить listCID в качестве входного параметра на my_fn или попытаться вернуть его в конце).

Возможно ли сохранить десять конструкций [email protected] через my_fn, которые будут использоваться позже? Я чувствую, что есть несколько проблем синтаксиса, которые я не совсем понимаю, что может объяснить, почему я застрял, и, кроме того, я был бы счастлив изменить название этого вопроса, если я не буду использовать соответствующую терминологию. Спасибо!

library(hexbin) 
library(GGally) 
library(ggplot2) 

set.seed(1) 

bindata <- data.frame(
    ID = paste0("ID", 1:100), 
    A = rnorm(100), B = rnorm(100), C = rnorm(100), 
    D = rnorm(100), E = rnorm(100)) 
    bindata$ID <- as.character(bindata$ID 
) 

maxVal <- max(abs(bindata[ ,2:6])) 
maxRange <- c(-1 * maxVal, maxVal) 

listCID <- c() 

my_fn <- function(data, mapping, ...){ 
    x <- data[ ,c(as.character(mapping$x))] 
    y <- data[ ,c(as.character(mapping$y))] 
    h <- hexbin(x=x, y=y, xbins=5, shape=1, IDs=TRUE, 
       xbnds=maxRange, ybnds=maxRange) 
    hexdf <- data.frame(hcell2xy(h), [email protected], [email protected]) 
    listCID <- c(listCID, [email protected]) 
    print(listCID) 
    p <- ggplot(hexdf, aes(x=x, y=y, fill=counts, hexID=hexID)) + 
      geom_hex(stat="identity") 
    p 
} 

p <- ggpairs(bindata[ ,2:6], lower=list(continuous=my_fn)) 
p 

enter image description here

+2

Вы можете добавить дополнительную информацию в качестве атрибута. Итак, после строки 'hexdf <- data.frame (...)' use 'attr (hexdf," cID ") <- h @ cID' (и удалите две строки кода listCID). Затем вы можете получить доступ, посмотрев на отдельные графики, то есть 'str (p [2,1])' и извлечь с помощью 'attr (p [2,1] $ data," cID ")' – user20650

ответ

6

Если я правильно понимаю вашу проблему правильно, это довольно легко, хотя и некрасиво, достигается с помощью оператора <<-.

С его помощью вы можете назначить нечто вроде глобальной переменной изнутри вашей функции.

Установить listCID <- NULL перед выполнением функции и listCID <<-c(listCID,[email protected]) внутри функции.

listCID = NULL 

my_fn <- function(data, mapping, ...){ 
    x = data[,c(as.character(mapping$x))] 
    y = data[,c(as.character(mapping$y))] 
    h <- hexbin(x=x, y=y, xbins=5, shape=1, IDs=TRUE, xbnds=maxRange, ybnds=maxRange) 
    hexdf <- data.frame (hcell2xy (h), hexID = [email protected], counts = [email protected]) 

    if(exists("listCID")) listCID <<-c(listCID,[email protected]) 

    print(listCID) 
    p <- ggplot(hexdf, aes(x=x, y=y, fill = counts, hexID=hexID)) + geom_hex(stat="identity") 
    p 
    } 

Более подробной информации о обзорном пожалуйста, обратитесь к Hadleys отличного Advanced R: http://adv-r.had.co.nz/Environments.html

0

В целом это не очень хорошая практика, чтобы попытаться вернуть два различные результат с одной функцией. В вашем случае вы хотите вернуть график и результат вычисления (идентификаторы идентификатора hexbin).

Лучше было бы рассчитать ваши результаты в шагах. Каждый шаг будет отдельной функцией. Результат первой функции (вычисление шестиугольников) можно затем использовать как вход для нескольких последующих функций (поиск идентификаторов и создание графика). Далее следует один из многих способов, которыми вы могли бы реорганизовать код:

  • calc_hexbins(), в котором вы создаете все hexbins. Эта функция может вернуть именованный список hexbins (например, список (AB = h1, AC = h2, BC = 43)). Это достигается путем перечисления всех возможных комбинаций вашего списка (A, B, C, D и E). Недостатком является то, что вы дублируете некоторую логику, которая уже находится в ggpairs().
  • gen_cids() берет hexbins в качестве входных данных и генерирует все идентификаторы cID. Это простая операция, когда вы выполняете цикл (или lappy) по всем элементам вашего списка и принимаете идентификатор cID.
  • create_plot() также принимает hexbins в качестве входных данных, и это функция, в которой вы фактически генерируете график. Здесь вы можете добавить дополнительный параметр для списка hexbins (есть функция wrap() в вашем пакете GGally для этого). Вместо того, чтобы вычислять гексбины, вы можете найти их в названном списке, который вы создали ранее, объединив A и B в строке.

Это позволяет избежать хакерских методов, таких как работа с атрибутами или использование глобальных переменных. Конечно, эти работы, но часто являются головной болью при сохранении кода. К сожалению, это также сделает ваш код немного дольше, но это может быть хорошо.

Смежные вопросы