我有一个小标题,其中包含每天不同级别的变量的值。
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循环的解决方案方面的帮助。谢谢:)
尝试一下。它会长期旋转数据框,加入截止点,然后在适用的情况下使用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)