#r #ggplot2 #shiny #3d #plotly
#r #ggplot2 #блестящий #3D #plotly
Вопрос:
У меня есть точечный график 3D, который отображается следующим образом:
3D-набор данных очень большой, поэтому я не могу включить его сюда. Можно попытаться ответить на этот вопрос, используя стандартные наборы данных, такие как mtcars
или iris
.
Моя попытка построить эту диаграмму рассеяния 3D:
x <- rbind(A_0,A_1,A_2,A_3)
fig1 <- x %>% plot_ly(x= ~x,y=~y,z = ~z, color= ~key,type="scatter3d", size = 0.5)
fig1
A_0, A_1, A_2, A_3
существуют ли разные 3 * n dataframes
, которые объединяются вместе с использованием rbind
и дифференцируются с помощью ключа, включенного в каждый dataframe
Я пытался подгонять поверхность различными методами, такими как add_surface()
, add_trace()
, изменение типа на 'mesh3D'
Но результирующая подгонка поверхности — это не то, что я хочу, мне нужна гладкая подгонка поверхности по этим данным разброса. Ошибка, которую я получаю, заключается в следующем: z is not a numeric matrix.
Есть ли лучший способ подгонки поверхности, чего мне здесь не хватает?
PS Я бы предпочел визуализировать график с ggplot()
помощью , plot_ly()
, ggplotly()
.
Ответ №1:
Вы могли бы сначала подогнать модель, используя что-то вроде gam()
, а затем построить прогнозы. Во-первых, мы можем подогнать GAM к данным. В этом случае hp
и wt
являются двумя независимыми переменными (т. Е. осями x
и y
на диаграмме выше). qsec
переменная отображается на оси z и является зависимой переменной в модели.
data(mtcars)
library(mgcv)
mod <- gam(qsec ~ te(hp) te(wt) ti(hp, wt), data=mtcars)
Далее нам нужно сделать некоторые прогнозы для модели при различных комбинациях hp
и wt
. Самый простой способ сделать это — создать последовательность значений для каждой переменной, которая идет от их минимумов к максимумам. Это то, что делают приведенные ниже команды. Он создает последовательность из 25 равномерно распределенных значений, идущих от минимума к максимуму каждой независимой переменной.
hp.seq <- seq(min(mtcars$hp, na.rm=TRUE), max(mtcars$hp, na.rm=TRUE), length=25)
wt.seq <- seq(min(mtcars$wt, na.rm=TRUE), max(mtcars$wt, na.rm=TRUE), length=25)
Далее мы можем создать функцию, которая будет генерировать прогнозы. Поскольку мы собираемся использовать outer()
ниже, мы должны заставить функцию принимать два ввода и x
и a y
. Пары x-y, которые мы собираемся передать, являются значениями hp
и wt
используются для прогнозов. Функция создает фрейм данных, который имеет одно наблюдение и две переменные — hp
и wt
. Он использует этот новый фрейм данных для генерации единого прогноза из модели с использованием predict()
функции.
predfun <- function(x,y){
newdat <- data.frame(hp = x, wt=y)
predict(mod, newdata=newdat)
}
Затем мы применяем эту функцию прогнозирования к последовательностям данных, которые мы сделали выше. Мы используем outer()
функцию outer-product для создания матрицы 25×25 прогнозируемых значений для каждой комбинации hp.seq
и wt.seq
. Перенос predfun
Vectorize()
предотвращает ошибки, связанные с проблемами длины замены.
fit <- outer(hp.seq, wt.seq, Vectorize(predfun))
Наконец, мы можем собрать все вместе plot_ly
. Мы используем add_marker()
для добавления точек и add_surface
добавления прогнозов.
plot_ly() %>%
add_markers(x = ~mtcars$hp, y=mtcars$wt, z=mtcars$qsec) %>%
add_surface(x = ~hp.seq, y = ~wt.seq, z = t(fit))
Комментарии:
1. Он работает нормально, но можете ли вы объяснить, как это работает, чтобы я мог изменять разные параметры для улучшения подгонки немного лучше, я особенно не мог понять эту строку: mod <- gam (qsec ~ te (hp) te (wt) ti (hp, wt), data = mtcars), а также функция прогнозирования.
2. @kolas0202 Я добавил некоторые пояснения выше.
gam()
Функция соответствует обобщенной аддитивной модели. Спецификация RHS (~te(hp) te(wt) ti(hp,wt)
) соответствует плавному взаимодействию двух переменных. Если хотите, вы можете заменить gam моделью Лесса:mod <- loess(qsec ~ hp*wt, data=mtcars)
и остальная часть кода будет работать так, как задумано. Я думаю, что вывод из этого, однако, заключается в том, что для построения гладкой поверхности вам нужно подогнать модель к данным.3. могу ли я добавить формулу в функцию лесса, как мы обычно делаем в 2D-данных, например, mod <- loess(formula = y~ poly(x, 4, raw = TRUE), data = s) . Работает ли это и для 3D-данных, чтобы получить подгонку поверхности, mod <- loess(формула = z ~ poly(x, y, 4,5, raw = TRUE), data = s)
4. Возможно, но если вам нужен многочлен, я бы просто использовал
lm(z~poly(x, 4, raw=TRUE) poly(y, 5, raw=TRUE), data=s)
. Опять же, тогда остальная часть функции должна работать должным образом. Это создало бы аддитивную модель вx
иy
, но она была бы гладкой и нелинейной.