简体   繁体   English

根据不同 tibble 的截止值更改 tibble 中不同列的值

[英]change value of different columns in a tibble based on cutoffs from a different tibble

I have a tibble which contains values for different variables at a daily level.我有一个 tibble,其中包含每天不同变量的值。

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

These variables need to be bound by certain min and max values which are found in another tibble as:这些变量需要受到在另一个小标题中找到的某些最小值和最大值的约束:

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

Now I want to go through my original df and change it so that every value below min is changed to min and every value above max is changed to max, where min and max are found in the cutoffs.现在我想通过我的原始 df 并更改它,以便将低于 min 的每个值更改为 min,并将高于 max 的每个值更改为 max,其中 min 和 max 在截止值中找到。

I currently do it in a for loop but I feel like a function like map could be used here, but I am not sure how to use it.我目前在 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)))

}

I would appreciate your help in creating a solution that does not use a for loop.感谢您帮助创建不使用 for 循环的解决方案。 Thanks :)谢谢 :)

Try this.尝试这个。 It pivots your dataframe long-wise, joins to the cutoffs, and then uses case_when to replace value where applicable:它长期旋转您的数据框,连接到截止点,然后在适用的情况下使用 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM