在 R 中,基于另一列替换跨时间序列的值

In R, replace values across time series based on another column

实际上这与我之前的问题有关:

但是我需要修改时间序列数据集中的值,但基于同一行但跨另一组时间序列列的条件。数据集如下所示:

#there are many more years (yrs) in the data set
product<-c("01","02")
yr1<-c("1","7")
yr2<-c("3","4")

#these follow the number of years
type.yr1<-c("mixed","number")
type.yr2<-c("number","mixed")

#this is a reference column to pull values from in case the type value is "mixed" 
mixed.rate<-c("1+5GBP","7+3GBP")

df<-data.frame(product,yr1,yr2,type.yr1,type.yr2,mixed.rate)

其中值 1 应替换为“1+5GBP”,4 应替换为“7+3GBP”。我正在考虑类似下面的内容 - 有人可以帮忙吗?

df %>% 
mutate(across(c(starts_with('yr'),starts_with('type'), ~ifelse(type.x=="mixed", mixed.rate.x, .x)))

最终结果应该是:

product<-c("01","02")
yr1<-c("1+5GBP","7")
yr2<-c("3","7+3GBP")
type.yr1<-c("mixed","number")
type.yr2<-c("number","mixed")
mixed.rate<-c("1+5 GBP","7+3GBP")

df<-data.frame(product,yr1,yr2,type.yr1,type.yr2,mixed.rate)

如果我对你的理解正确,我认为你可能会受益于更长时间的旋转,替换单个 if_else 中的值,然后摆动回宽。

df %>% 
  pivot_longer(cols = -c(product,mixed.rate), names_to=c(".value", "year"), names_pattern = "(.*)(\d)") %>% 
  mutate(yr=if_else(type.yr=="mixed",mixed.rate,yr)) %>% 
  pivot_wider(names_from=year, values_from=c(yr,type.yr),names_sep = "")

输出:

  product mixed.rate yr1     yr2    type.yr1 type.yr2
  <chr>   <chr>      <chr>   <chr>  <chr>    <chr>   
1 01      1+5 GBP    1+5 GBP 3      mixed    number  
2 02      7+3GBP     7       7+3GBP number   mixed   

如果您愿意使用 base R 而不是 dplyr,那么以下将产生您需要的输出:

for (i in 1:2) {
  df[,paste0('yr',i)] <- if_else(df[,paste0('type.yr',i)]=='mixed',df[,'mixed.rate'],df[,paste0('yr',i)])
}

您可以使用 pivot_longer 在一列中显示所有年份,在另一列中显示 type.yrs。如果 type.yr 列混合,则 record 1 变为 1+5GBP,4 变为 7+3GBP。然后 pivot_wider

df %>%
  pivot_longer(contains('yr'), names_to = c('.value','grp'),
               names_pattern = '(\D+)(\d+)') %>%
  mutate(yr = ifelse(type.yr == 'mixed', recode(yr, '1' = '1+5GBP', '4' = '7+3GBP'), yr)) %>%
  pivot_wider(c(product, mixed.rate), names_from = grp,
              values_from = c(yr, type.yr), names_sep = '')

# A tibble: 2 x 6
  product mixed.rate yr1    yr2    type.yr1 type.yr2
  <chr>   <chr>      <chr>  <chr>  <chr>    <chr>   
1 01      1+5GBP     1+5GBP 3      mixed    number  
2 02      7+3GBP     7      7+3GBP number   mixed