Итеративно назначать имена переменных для вычислений, выполняемых в списке в списке в R?

У меня уже некоторое время возникла проблема в 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...

  1. Существует ли простой способ присвоения уникальных имен переменных для этих отдельных списков в расчетах списка? Потому что в его нынешнем виде код делает то, что должен делать с вычислениями ошибок, но сохраняет только последний вычисленный список (model3.

В идеале он должен что-то делать, вычисляя нормальную ошибку для 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

Таким образом, как только этот цикл будет выполнен, у меня будет нормальная ошибка для каждой модели.

Вам будет намного легче помочь, если вы сможете (а) сократить свой код до краткого, простого, воспроизводимого примера и (б) предоставить точный ожидаемый результат. Для (а) это даже не обязательно должен быть ваш фактический вариант использования, имена переменных и т. д., Просто что-то, что изолирует проблему, с которой вы столкнулись, и упрощает ее проверку и обдумывание. Прямо сейчас в вашем сообщении много кода, который не подходит для воспроизведения основной проблемы. Re (b), показывающий текущий выход по сравнению с ожидаемым выходом, даже если он усечен, чтобы показать только первый или два результата, позволяет легко проверить, являются ли решения подходящими.

andrew_reece 11.12.2020 20:00

Привет @andrew_reece, я обновлю код, спасибо за ответ!

Andrew Coleman 12.12.2020 04:05

@andrew_reece, я обновил код. Дайте мне знать, если это более понятно. Я обобщил изрядную сумму.

Andrew Coleman 12.12.2020 04:28

Вы имеете в виду вложение циклов for? Для меня это не имеет смысла, учитывая, что вы хотите применить вычитание. Если у вас все в порядке с пакетом purrr, вы можете сделать purrr::map2(totalmodeldata, totalverificationdata, ~ .x - .y)

Phil 12.12.2020 05:16

С ним намного легче работать, спасибо. Обратите внимание, что вы дважды указали verification_model1 в totalverificationdata.

andrew_reece 12.12.2020 05:47

По вопросу @Phil, было бы полезно, если бы вы могли предоставить ожидаемый результат. Это прояснит, действительно ли вы хотите получить оценку разницы между одним значением в totalmodeldata и каждым значением в totalverificationdata. Например, вам действительно нужна разница между значением в model1 и каждым значением в verification_model1/2/3? Это то, что будет вычислять ваш текущий код.

andrew_reece 12.12.2020 05:49

@Phil, похоже, что purr несовместим с 4.0.2, и я не знаком с этим пакетом. Будет ли эта функция выполнять простое вычитание для каждого списка в моих «итоговых» списках? Спасибо.

Andrew Coleman 12.12.2020 22:45

@andrew_reece, не хотел дважды ставить verification_model1. Должен был быть verification_model3. Я сделал раздел обновления типа вывода, который я хотел бы. Чтобы уточнить, я хочу разницу между моделью 1 и проверкой 1, моделью 2 и проверкой 2 и так далее. Не model1 для всех данных проверки. Я попытался упростить это в обновлении. Спасибо всем за помощь.

Andrew Coleman 12.12.2020 22:48

Спасибо за разъяснение. В этом случае я бы рекомендовал удалить вложенный цикл for, который у вас есть в вашем сообщении. Вы можете проверить с помощью простого теста, что это приведет к гораздо большему количеству сравнений, чем желаемый результат. (Также, пожалуйста, исправьте опечатку verification_model1.)

andrew_reece 12.12.2020 22:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот решение с использованием вложенного 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.

Andrew Coleman 13.12.2020 00:00

и это функция, которая выдает ошибку: GFSmaxT_Norm_Error <- map2_df(GFSmaxT, verifmaxT, function(model, verify) { map2_dbl(model, verify, ~.x - .y) } )GFSmaxT представляет model1 и verifmaxT представляет verification_model1

Andrew Coleman 13.12.2020 00:06

это означает, что у вас не одинаковое количество значений в наборах model и verify. я не уверен, что это может означать, поскольку в вашем исходном сообщении говорилось, что вы хотите сравнить конкретное значение model с соответствующим элементом в verify. но я вижу, что у вас есть tibbles, что также отличается от ваших первоначальных спецификаций, где вы говорили об использовании списков. показанная вами ошибка имеет как минимум 5 столбцов в вашем фрейме данных. похоже, вам может понадобиться сузить все, что есть в вашей таблице, до только векторов model и verify.

andrew_reece 13.12.2020 00:16

Другие вопросы по теме