#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, но это не работает. Не могли бы вы посоветовать, какую функцию лучше всего было бы вложить в нее снова?