基于来自不同小齿的截止值的小齿中不同列的变化值

问题描述 投票:2回答:1

我有一个小标题,其中包含每天不同级别的变量的值。

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))

现在,我想遍历原始df并进行更改,以便将min以下的每个值都更改为min,并将max以上的每个值都更改为max,其中在临界值中找到min和max。

我目前在for循环中执行此操作,但是我觉得这里可以使用类似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)))

}

非常感谢您在创建不使用for循环的解决方案方面的帮助。谢谢:)

r dplyr purrr
1个回答
3
投票

尝试一下。它会长期旋转数据框,加入截止点,然后在适用的情况下使用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)
推荐问答
热门问答
最新问答