Во-первых, я думаю, что нам нужно изменить ваши данные из «широкого» в «высокий» формат.Это удовлетворит комментарий Райана о том, что вы не можете выполнять линейную регрессию с одной строкой - он технически прав, но я думаю, что он упускает из виду тот факт, что у вас на самом деле 4-5 наблюдений в строке, а не 1. ( Комментарий с момента удаления.)
(Второе: никогда не называйте переменную data
. Если вы забудете создать ее в новом сеансе R, все функции, которые зависят от нее, будут сбои любопытным и часто неинтуитивным способом вместоожидаемое более простое сообщение об ошибке Error: object 'data' not found
. Я буду использовать dat
с вашим кодом создания.)
Это продемонстрировано на примере нескольких пакетов из tidyverse
:
library(dplyr)
library(tidyr)
library(purrr)
Изменение формыВо-первых, вы перечисляете как km1
, km2
и т. д., но это категориальные переменные, а не числа, и я предполагаю, что вы хотите, чтобы числа хранились в них.Так что то, что у вас есть в качестве имени столбца (km1
), действительно должно быть данными (km = 1
).(О, и я убираю NA
, так как они не помогают кормить модель. Мы вернем их позже.)
datlong <- dat %>%
gather(km, dens, -cities) %>%
mutate(km = as.numeric(gsub("km", "", km))) %>%
rename(city = cities) %>%
filter(complete.cases(.))
datlong
# city km dens
# 1 city1 1 6.265509
# 2 city2 1 6.372124
# 3 city3 1 6.572853
# 4 city1 2 5.908208
# 5 city2 2 5.201682
# 6 city3 2 5.898390
# 7 city1 3 4.944675
# 8 city2 3 4.660798
# 9 city3 3 4.629114
# 10 city1 4 3.500000
# 11 city2 4 3.200000
Теперь проблема в том, как сделать регрессию для каждогогород.Во-первых, давайте немного «наведем порядок», поместив все городские данные в одну «ячейку» кадра.
datnested <- datlong %>%
group_by(city) %>%
nest(.key = "citydat")
datnested
# # A tibble: 3 x 2
# city citydat
# <fct> <list>
# 1 city1 <tibble [4 x 2]>
# 2 city2 <tibble [4 x 2]>
# 3 city3 <tibble [3 x 2]>
Теперь мы можем запустить регрессию для каждого набора данных:
datmodel <- datnested %>%
mutate(model = map(citydat, ~ lm(dens ~ km, data = .x)))
datmodel
# # A tibble: 3 x 3
# city citydat model
# <fct> <list> <list>
# 1 city1 <tibble [4 x 2]> <S3: lm>
# 2 city2 <tibble [4 x 2]> <S3: lm>
# 3 city3 <tibble [3 x 2]> <S3: lm>
Заметили встроенные модели в раме?Каждый выглядит примерно так:
datmodel$model[[1]]
# Call:
# lm(formula = dens ~ km, data = .x)
# Coefficients:
# (Intercept) km
# 7.470 -0.926
Теперь , что можно использовать в другом месте.Давайте запустим прогноз:
predkm <- 1:5
datpred <- datmodel %>%
mutate(pred = map(model, ~ data_frame(km = predkm, preddens = predict(.x, newdata = data.frame(km=predkm)))))
datpred
# # A tibble: 3 x 4
# city citydat model pred
# <fct> <list> <list> <list>
# 1 city1 <tibble [4 x 2]> <S3: lm> <tibble [5 x 2]>
# 2 city2 <tibble [4 x 2]> <S3: lm> <tibble [5 x 2]>
# 3 city3 <tibble [3 x 2]> <S3: lm> <tibble [5 x 2]>
Аналогично:
datpred$pred[[1]]
# # A tibble: 5 x 2
# km preddens
# <int> <dbl>
# 1 1 6.54
# 2 2 5.62
# 3 3 4.69
# 4 4 3.77
# 5 5 2.84
Хорошо, так как мы можем получить один результирующий кадр?
datpredonly <- datpred %>%
select(city, pred) %>%
unnest()
datpredonly
# # A tibble: 15 x 3
# city km preddens
# <fct> <int> <dbl>
# 1 city1 1 6.54
# 2 city1 2 5.62
# 3 city1 3 4.69
# 4 city1 4 3.77
# 5 city1 5 2.84
# 6 city2 1 6.37
# 7 city2 2 5.36
# 8 city2 3 4.36
# 9 city2 4 3.35
# 10 city2 5 2.34
# 11 city3 1 6.67
# 12 city3 2 5.70
# 13 city3 3 4.73
# 14 city3 4 3.76
# 15 city3 5 2.78
Если вы хотитесравните с оригиналом (для ошибок и т. д.), попробуйте:
full_join(datlong, datpredonly, by = c("city", "km")) %>%
arrange(city, km)
# city km dens preddens
# 1 city1 1 6.265509 6.543607
# 2 city1 2 5.908208 5.617601
# 3 city1 3 4.944675 4.691595
# 4 city1 4 3.500000 3.765589
# 5 city1 5 NA 2.839583
# 6 city2 1 6.372124 6.367239
# 7 city2 2 5.201682 5.361514
# 8 city2 3 4.660798 4.355788
# 9 city2 4 3.200000 3.350063
# 10 city2 5 NA 2.344337
# 11 city3 1 6.572853 6.671989
# 12 city3 2 5.898390 5.700119
# 13 city3 3 4.629114 4.728249
# 14 city3 4 NA 3.756380
# 15 city3 5 NA 2.784510
Итак, вы обсуждали использование экспоненциальной регрессии: это обрабатывается в одном вызове lm
ранее в ходе выполнения.Не стесняйтесь переходить с dens ~ km
на конкретные экспоненциальные формулы.
Я разбил все это на компоненты.Вот длинная цепочка.
predkm <- 1:5
datnestedmodels <- datlong %>%
group_by(city) %>%
nest(.key = "citydat") %>%
mutate(
model = map(citydat, ~ lm(dens ~ km, data = .x)),
pred = map(model, ~ data_frame(km = predkm,
preddens = predict(.x, newdata = data.frame(km=predkm))))
)
datnestedmodels %>%
select(city, pred) %>%
unnest()
Если вы предпочитаете (или нуждаетесь) в «широком» формате:
datnestedmodels %>%
select(city, pred) %>%
unnest() %>%
spread(km, preddens, sep = "")
# # A tibble: 3 x 6
# city km1 km2 km3 km4 km5
# <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 city1 6.54 5.62 4.69 3.77 2.84
# 2 city2 6.37 5.36 4.36 3.35 2.34
# 3 city3 6.67 5.70 4.73 3.76 2.78