Используйте таблицу подстановки во фрейме данных для стандартизации данных во вложенном списке

#r #lookup

Вопрос:

Привет, у меня есть много гидрологических данных о потоке(Q), которые мне нужно стандартизировать. У меня есть большая вложенная таблица с макетом, подобным приведенному ниже, которую мне нужно сохранить:

 Flowtestlist <- list(list("910" = data.frame( Q=c(650, 720, 550, 580, 800)),
            "950" = data.frame( Q=c(550, 770, 520, 540, 790))),
            list ("910" = data.frame( Q=c(450, 620, 750, 580, 800)),
             "950" = data.frame( Q=c(650, 750, 580, 520, 890))))
 

В приведенном выше списке у меня есть уровни [[1]] и [[2]], на самом деле у меня их 9, и это также номера моделей. В каждой модели у меня есть 18 поддиапазонов с номерами 910, 950 и т. Д. (В приведенном выше примере для простоты всего два поддиапазона 910, 950). Подосновы содержат данные о потоке (Q).

У меня также есть таблица поиска:

 test_model <- c(1,1,2,2)
test_subbasin <- c(910,950,910,950)
Q_mean <- c(870,765,823,689)
FlowtestDF <- data.frame(test_model, test_subbasin, Q_mean)
 

Этот фрейм данных состоит из данных со средним потоком за базовый период (Q_mean) для каждой модели и подосновы. Это моя таблица поиска.
Я хочу взять каждый Q из вложенной таблицы, найти соответствующий номер модели и поддиапазон в таблице поиска и разделить его, чтобы получить стандартизированный поток Q_st.

 fun_st <- function(x, y=FlowtestDF) { x$Q_st <- x$Q/y$Q_mean
                          x <- x}

testresult  <- lapply( Flowtestlist, lapply, fun_st)
 

К сожалению, это не работает. Насколько я понимаю, функция не может найти подходящее расположение нужного номера в таблице поиска (модель и поддиапазон). Как я могу это исправить?

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

1. Ваша жизнь станет намного проще, если вы избавитесь от «того, что мне нужно сохранить». Если эта структура данных необходима для конкретной задачи, вы всегда можете воссоздать ее заново. Но сначала я бы преобразовал данные в «аккуратный» фрейм данных. Это позволяет использовать эффективные стандартные подходы.

Ответ №1:

Привет, я понимаю, что вы хотите сохранить исходную структуру данных,

однако неясно, куда поместятся новые значения для стандартизированного потока Q_st.

С программной точки зрения то, что вы пытаетесь здесь сделать; использование listapply с возможностью поиска по списку безымянных подсписков одномерных фреймов данных (все с одинаковыми именами и все столбцы с именем «Q») — очень сложно ( по крайней мере для меня)

Я бы предпочел избавить себя от этой головной боли и, как предложил Роланд, сделать это аккуратно.

Для этого есть много решений; Вот как бы я это сделал:

 library(purrr);library(tidyr);library(dplyr)

 

1. Реконструировать

 Flowtest_df<-map_df(Flowtestlist, ~.x, .id = "test_model") %>%
  pivot_longer(2:3, names_to = "test_subbasin")
 

преобразуйте столбцы таблиц поиска в символы, чтобы объединить таблицы

 FlowtestDF$test_model<-as.character(FlowtestDF$test_model)
FlowtestDF$test_subbasin<-as.character(FlowtestDF$test_subbasin)
 

можно пропустить, если вы назначите его в качестве символов

2. присоединяйтесь к ним

 Flowtest_df %>% left_join(FlowtestDF) %>%
  mutate(Q_st=value$Q/Q_mean) # 3. do the calculation
 

Это даст вам такой вывод, который будет намного чище для чтения как для машины, так и для нас, смертных.

 # A tibble: 6 × 5
  test_model test_subbasin value$Q Q_mean  Q_st
  <chr>      <chr>           <dbl>  <dbl> <dbl>
1 1          910               650    870 0.747
2 1          950               550    765 0.719
3 1          910               720    870 0.828
 

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

1. Извините, но выполнение кода на первом этапе, предложенном вами, приводит к ошибке: аргумент 1 не может быть списком, содержащим фреймы данных.

2. странно, что он отлично работает с моей установкой. каков ваш вывод packageVersion(«мурлыканье»)?

3. это 0.3.4. Вы знаете, как это исправить?

4. idk код работает, на моей стороне у меня есть purrr 0.3.4, версия 4.1.0 R, dplyr ‘1.0.7’, tidyr ‘1.1.3’.

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