У меня уже некоторое время возникла проблема в R studio, и я хотел бы предварить, что я все еще довольно новичок в R и до сих пор не знаю всех «самых быстрых» методов работы, но любая помощь и терпение были бы потрясающими. .
Я исследователь, которому нужно рассчитать оценки навыков для моделей погоды на разных метеостанциях, и у меня есть тысячи точек данных для повторения, и я решил, что самый простой способ сделать это - прочитать файлы и сохранить каждый файл как отдельный список в списке .
После этого я бы перебирал каждый список в списках и вычислял различные оценки ошибок (нормальная ошибка, RMSE и т. д.), Избавляя меня от необходимости копировать и вставлять около 121 различных циклов. Этот метод ведения дел явно А) не является хорошим методом или Б) у меня нет четкого представления о том, как лучше всего это сделать.
Итак, ниже приведен краткий пример:
# The weather model forecasts
model1 <- c(1:15)
model2 <- c(1:15)
model3 <- c(1:15)
# What actually happened (verification/measured values)
verification_model1 <- c(1:15)
verification_model2 <- c(1:15)
verification_model3 <- c(1:15)
# List of lists containging total model data
totalmodeldata <- list(model1,model2,model3)
totalverificationdata <-list(verification_model1,verification_model2,verification_model3)
# Calculate normal error
for (val in totalmodeldata){
for (ob in totalverificationdata){
uniquevarname <- val - ob # here is the issue!
}
}
Итак, вот моя единственная проблема, чтобы сделать это простым Q/A...
В идеале он должен что-то делать, вычисляя нормальную ошибку для model1 VS. Verification_model1 присваивает данные переменной, затем переходит ко вторым спискам и так далее, так что у меня есть обычная ошибка для model1, model2 и model3.
ОБНОВЛЯТЬ: Хорошо, мы куда-то движемся. Это выход, который я хотел бы... После объявления данных модели (model1..2..3 и т. д.) и данных проверки (verifcation_model1..2..3 и т. д.) в «общих» списках цикл for или аналогичная функция будет проходить и выполнять приведенное ниже вычитание для КАЖДОЙ модели и список данных проверки:
unqiue_var_error1 <- model1 - verification_model1
unqiue_var_error2 <- model2 - verification_model2
unqiue_var_error3 <- model3 - verification_model3
Выходные/сохраненные данные будут выглядеть как простой вектор данных для каждой модели... Вот фактический вывод нормальной ошибки из моей работы:
> head(model1,n = 15L)
[1] -6 0 1 0 -4 -2 2 0 -3 -2 -3 -5 -5 -5 -5
Таким образом, как только этот цикл будет выполнен, у меня будет нормальная ошибка для каждой модели.
Привет @andrew_reece, я обновлю код, спасибо за ответ!
@andrew_reece, я обновил код. Дайте мне знать, если это более понятно. Я обобщил изрядную сумму.
Вы имеете в виду вложение циклов for? Для меня это не имеет смысла, учитывая, что вы хотите применить вычитание. Если у вас все в порядке с пакетом purrr
, вы можете сделать purrr::map2(totalmodeldata, totalverificationdata, ~ .x - .y)
С ним намного легче работать, спасибо. Обратите внимание, что вы дважды указали verification_model1
в totalverificationdata
.
По вопросу @Phil, было бы полезно, если бы вы могли предоставить ожидаемый результат. Это прояснит, действительно ли вы хотите получить оценку разницы между одним значением в totalmodeldata
и каждым значением в totalverificationdata
. Например, вам действительно нужна разница между значением в model1
и каждым значением в verification_model1/2/3
? Это то, что будет вычислять ваш текущий код.
@Phil, похоже, что purr несовместим с 4.0.2, и я не знаком с этим пакетом. Будет ли эта функция выполнять простое вычитание для каждого списка в моих «итоговых» списках? Спасибо.
@andrew_reece, не хотел дважды ставить verification_model1
. Должен был быть verification_model3
. Я сделал раздел обновления типа вывода, который я хотел бы. Чтобы уточнить, я хочу разницу между моделью 1 и проверкой 1, моделью 2 и проверкой 2 и так далее. Не model1 для всех данных проверки. Я попытался упростить это в обновлении. Спасибо всем за помощь.
Спасибо за разъяснение. В этом случае я бы рекомендовал удалить вложенный цикл for, который у вас есть в вашем сообщении. Вы можете проверить с помощью простого теста, что это приведет к гораздо большему количеству сравнений, чем желаемый результат. (Также, пожалуйста, исправьте опечатку verification_model1
.)
Вот решение с использованием вложенного purrr::map2.
(На самом деле вам не нужно вложенное сопоставление, оно просто позволяет обернуть результаты в один фрейм данных.)
library(tidyverse)
map2_df(totalmodeldata, totalverificationdata,
function(model, verify) {
map2_dbl(model, verify, ~.x - .y)
}
)
# A tibble: 10 x 3
model1 model2 model3
<dbl> <dbl> <dbl>
1 -1.22 -0.611 -1.50
2 1.82 0.911 1.71
3 3.06 1.53 3.84
4 -1.40 -0.700 -1.37
5 -1.33 -0.665 -1.27
6 1.57 0.787 2.43
7 0.252 0.126 0.482
8 1.77 0.886 1.14
9 -0.200 -0.100 -0.543
10 0.642 0.321 0.419
Данные:
# added randomness to avoid having all zeros show up in diff scores
# The weather model forecasts
set.seed(123)
n <- 10
model1 <- rnorm(n)
model2 <- model1 * .5
model3 <- model1 * 1.5
# What actually happened (verification/measured values)
set.seed(234)
verification_model1 <- rnorm(n)
verification_model2 <- verification_model1 * .5
verification_model3 <- verification_model1 * 1.5
# List of lists containging total model data
totalmodeldata <-
list(model1, model2, model3) %>% set_names('model1', 'model2', 'model3')
totalverificationdata <-
list(verification_model1, verification_model2, verification_model1) %>%
set_names('ver_model1', 'ver_model2', 'ver_model3')
Примечание. Пакет purrr
представляет собой аккуратную версию базовых функций семейства R apply
(и, согласно комментарию OP, он совместим с R >= 3.2).
Это фантастика! Это решение как раз то, что мне нужно. Моя единственная проблема, которая осталась, это то, что у каждой модели размеры различаются. При этом я внедрил ваше решение в свою работу и протестировал его на своих моделях model1 и verify_model1 и получил ошибку для разных размеров. есть ли обходной путь? Вот результат: Error: Tibble columns must have compatible sizes. * Size 994: Column
KGRR. * Size 1012: Column
KGFL. * Size 1025: Column
PAJN. * Size 1041: Column
KMAF. * Size 1062: Column
KMDL. ℹ … and 1 more problem.
и это функция, которая выдает ошибку: GFSmaxT_Norm_Error <- map2_df(GFSmaxT, verifmaxT, function(model, verify) { map2_dbl(model, verify, ~.x - .y) } )
GFSmaxT
представляет model1
и verifmaxT
представляет verification_model1
это означает, что у вас не одинаковое количество значений в наборах model
и verify
. я не уверен, что это может означать, поскольку в вашем исходном сообщении говорилось, что вы хотите сравнить конкретное значение model
с соответствующим элементом в verify
. но я вижу, что у вас есть tibble
s, что также отличается от ваших первоначальных спецификаций, где вы говорили об использовании списков. показанная вами ошибка имеет как минимум 5 столбцов в вашем фрейме данных. похоже, вам может понадобиться сузить все, что есть в вашей таблице, до только векторов model
и verify
.
Вам будет намного легче помочь, если вы сможете (а) сократить свой код до краткого, простого, воспроизводимого примера и (б) предоставить точный ожидаемый результат. Для (а) это даже не обязательно должен быть ваш фактический вариант использования, имена переменных и т. д., Просто что-то, что изолирует проблему, с которой вы столкнулись, и упрощает ее проверку и обдумывание. Прямо сейчас в вашем сообщении много кода, который не подходит для воспроизведения основной проблемы. Re (b), показывающий текущий выход по сравнению с ожидаемым выходом, даже если он усечен, чтобы показать только первый или два результата, позволяет легко проверить, являются ли решения подходящими.