изменить значение разных столбцов в таблице на основе отсечений из другой таблицы - PullRequest
2 голосов
/ 01 апреля 2020

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

library(lubridate)
library(tidyverse)


df <- tibble::tibble(date = seq.Date(ymd('2019-01-01'), ymd('2019-03-31'), by = 1),
                     high = sample(-5:100, 90, replace = T),
                     low = sample(-25:50, 90, replace = T),
                     sd = sample(5:25, 90, replace = T))

Эти переменные должны быть связаны определенными минимальными и максимальными значениями, которые можно найти в другой таблице как:

cutoffs <- tibble::tibble(var_name = c('high', 'low', 'sd'),
                      min = c(0, -5, 10),
                      max = c(75, 15, 15))

Теперь я хочу go через мой исходный df и изменить его так, чтобы каждое значение ниже min было изменено на min, а каждое значение выше max изменилось на max, где min и max находятся в срезах.

В настоящее время я делаю это в течение для l oop, но я чувствую, что здесь можно использовать функцию типа map, но я не уверен, как ее использовать.

for (i in 1:3){


a <- cutoffs$var_name[[i]]
  print(a)
  min <- cutoffs$min[[i]]
  max <- cutoffs$max[[i]]

  df <- df %>%
    mutate(!!a := ifelse(!!as.name(a) < min, min, !!as.name(a)),
           !!a := ifelse(!!as.name(a) > max, max, !!as.name(a)))

}

I Буду признателен за помощь в создании решения, которое не использует для l oop. Спасибо:)

1 Ответ

3 голосов
/ 01 апреля 2020

Попробуйте это. Он поворачивает ваш фрейм данных в долгосрочной перспективе, присоединяется к обрезкам, а затем использует case_when для замены значения, где это применимо:

library(lubridate)
library(tidyverse)


df <- tibble::tibble(date = seq.Date(ymd('2019-01-01'), ymd('2019-03-31'), by = 1),
                     high = sample(-5:100, 90, replace = T),
                     low = sample(-25:50, 90, replace = T),
                     sd = sample(5:25, 90, replace = T)) %>% 
  pivot_longer(-date, names_to = "var_name", values_to = "value")

df

cutoffs <- tibble::tibble(var_name = c('high', 'low', 'sd'),
                          min = c(0, -5, 10),
                          max = c(75, 15, 15))

df %>% 
  left_join(cutoffs) %>% 
  mutate(value_new = case_when(value > max ~ max,
                           value < min ~ min,
                           TRUE ~ as.double(value))) %>% 
  select(date, var_name, value, value_new, min, max)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...