ggplot для объектов, хранящихся в 3D-массиве

#r #list #ggplot2 #plot #line

#r #Список #ggplot2 #график #строка

Вопрос:

Я написал следующий код, который работает и отображает то, что я хочу, но если бы я хотел использовать ggplot для построения графика, как я мог бы это сделать?

 myseq<-seq(from = 1, to = 99, by = 5)
mtx <- array(rnorm(880,0,1) ,c(4,11,length(myseq)))

plot(myseq,mtx[1,1,],type = "l", col=1) 
lines(myseq,mtx[1,2,],type = "l",col=2)
lines(myseq,mtx[1,3,],type = "l",col=3)
lines(myseq,mtx[1,4,],type = "l",col=4)
lines(myseq,mtx[1,5,],type = "l",col=5)
lines(myseq,mtx[1,6,],type = "l",col=6)
lines(myseq,mtx[1,7,],type = "l",col=7)
lines(myseq,mtx[1,8,],type = "l",col=8)
lines(myseq,mtx[1,9,],type = "l",col=9)
lines(myseq,mtx[1,10,],type = "l",col=10)
lines(myseq,mtx[1,11,],type = "l",col=11)
  

После запуска этого, скажем, я получаю график, как показано ниже, теперь, как это сделать, используя ggplot2?

введите описание изображения здесь

введите описание изображения здесь

Комментарии:

1. Равно threshold 19?

2. Когда я запускаю этот код (заменяя 19 на threshold ), я не получаю этот график, я получаю ошибки о длинах векторов. Когда я меняю myseq значение на длину 19 (делая вывод, что оно должно совпадать с одним из элементов массива dimm), я получаю график, который выглядит совсем не так. Возможно, я догматичен, но … если вы собираетесь сказать, что получаете график из кода, возможно, вы могли бы использовать код, который вы нам даете?

3. Хорошая правка. Обратите внимание, что, поскольку вы заполняете массив 836 случайными числами в размерах 4*11*20 (880), вы перерабатываете 44 своих случайных чисел. Это не меняет способа его построения, но если это точно имитирует ваш реальный процесс, то ваши данные повреждены / искажены.

4. Прошу прощения. Я изменил тему своего вопроса, и предоставленные ошибки теперь исчезли.

5. 4*11*19 потому что длина myseq равна 19.

Ответ №1:

ggplot2 предпочитает фреймы данных, а для чего-то подобного — фреймы в длинном формате.

Вот простой способ сделать это.

Во-первых, воспроизводимые случайные данные.

 set.seed(42)
myseq<-seq(from = 1, to = 99, by = 5)
mtx <- array(rnorm(880,0,1) ,c(4,11,length(myseq)))
mtx[1,1:4,1:4]
#            [,1]       [,2]       [,3]          [,4]
# [1,]  1.3709584 -1.3682810  0.9333463  6.288407e-05
# [2,]  0.4042683 -0.4314462  0.6503486 -1.173196e-01
# [3,]  2.0184237  1.5757275 -1.1317387 -8.610730e-02
# [4,] -1.3888607  0.6792888  1.2009654 -4.138688e-01
  

Отсюда мы можем в основном преобразовать этот 3D-массив в четыре столбца data.frame , где три столбца указывают оси, а четвертый — фактическое значение.

 melted_mtx <- reshape2::melt(mtx[1,,,drop=FALSE])
str(melted_mtx, vec.len=15)
# 'data.frame': 220 obs. of  4 variables:
#  $ Var1 : int  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
#  $ Var2 : int  1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 6 7 8 9 10 11 1 2 3 4 5 ...
#  $ Var3 : int  1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 ...
#  $ value: num  1.371 0.404 2.018 -1.389 -0.284 -0.307 1.895 0.46 1.035 -0.784 0.206 -1.368 -0.431 1.576 0.679 -0.367 -0.727 0.921 0.624 ...
  

Поскольку вы хотите построить график myseq по оси x, мы можем сделать замену этим. Это в третьей переменной здесь, Var3 . Я проверю, что это правильная длина, а затем выполню замену:

 lapply(melted_mtx[-4], table)
# $Var1
#   1 
# 220 
# $Var2
#  1  2  3  4  5  6  7  8  9 10 11 
# 20 20 20 20 20 20 20 20 20 20 20 
# $Var3
#  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
# 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 

melted_mtx$Var3 <- myseq[melted_mtx$Var3]
lapply(melted_mtx[-4], table)
# $Var1
#   1 
# 220 
# $Var2
#  1  2  3  4  5  6  7  8  9 10 11 
# 20 20 20 20 20 20 20 20 20 20 20 
# $Var3
#  1  6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96 
# 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 
  

Мы можем использовать это и передавать его в ggplot2 rather напрямую.

 library(ggplot2)
ggplot(melted_mtx, aes(Var3, value, group = Var2, color = factor(Var2)))  
  geom_line()
  

ggplot2 плоскости 1

Базовый графический график этого (вашего кода) отображает:

базовая графика

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

Выше я редактировал только melt первую плоскость массива. Если бы вы сделали весь массив, то это выглядело бы так:

 melted_mtx <- reshape2::melt(mtx)
melted_mtx$Var3 <- myseq[melted_mtx$Var3]
ggplot(melted_mtx, aes(Var3, value, group = interaction(Var1, Var2),
                       color = interaction(Var1, Var2)))  
  geom_line()
  

ggplot2 со всеми плоскостями

Очевидно, что это немного сложно, но с использованием interaction вы можете группировать по нескольким переменным. Здесь требуется группировка, поскольку без нее ggplot2 будут пытаться соединить все точки в одну линию, что обычно бесполезно. Обычно можно обойтись без использования только color= для указания групп, но я часто включаю и group= то, и другое, и color= в случае, если я позже изменю, как цвета / типы линий / формы /… определены, и группы случайно изменены.

Комментарии:

1. не могу ли я построить myseq по оси X? Я не очень понимаю пакет reshape.

2. здесь я понимаю, что длина myseq отображается по оси x.

3. Это должна быть простая операция «замены», поскольку индекс в этом измерении массива также (по определению массива) является индексом myseq . . Смотрите мою правку.

4. Большое вам спасибо. Это было очень полезно. Теперь мне нужно найти способ запустить все это в повторяющейся функции. Я не знал, что ggplot хранит все объекты как глобальный символ. Пробовал melted_mtx $ Var3, melted_mtx $value внутри aes, давайте посмотрим.