代码之家  ›  专栏  ›  技术社区  ›  jakes

将后续变量的最小值累积到一列中

  •  1
  • jakes  · 技术社区  · 7 年前

    对于附加的数据,我希望将所选列的最小值拉出来,并将它们累积到 (Intercept) 列。剩下的变量应该是原始变量值和减去的最小值之间的差。我已经为一个选定的列编写了一个函数,并尝试使用 purrr:map_at 在少数选定列上调用它。但是下面的代码不起作用-不仅它不提取最小值,而且还返回后续日期的列表,而我显然希望保留 data.frame 结构。

    structure(list(`2016-01-01` = c(19.612765930918, 0.0139082609319898, 
    0.298043103003794, -0.217012113254805), `2016-01-02` = c(19.612765930918, 
    0.153780074988214, 0.317999312583603, -0.192164881529573), `2016-01-03` = c(19.612765930918, 
    0.150571795109967, 0.515644453462975, -0.269251568581305), `2016-01-04` = c(19.612765930918, 
    0.142512722884255, 0.261814150174792, -0.160625206980914), `2016-01-05` = c(19.612765930918, 
    0.0778498178207942, 0.464855455837326, -0.15224027496774), `2016-01-06` = c(19.612765930918, 
    0.0314062544574153, 0.278014325308919, -0.19657100740319)), class = "data.frame", row.names = c("(Intercept)", 
    "x1", "x2", "x3"))
    
    min_to_base <- function(impacts, var) {
      var <- ensym(var)
    
      impacts %>% 
        t() %>% 
        as.data.frame() %>% 
        mutate(min = min(!!var),
               !!var := !!var - min,
               `(Intercept)` = `(Intercept)` + min) %>% 
        select(-min)
    }
    
    impacts %>% 
      map_at(c('x1', 'x2'), ~min_to_base(., .x))
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   IceCreamToucan    7 年前

    所以,你要减去 x1 x2 从这些列中,将这些最小值添加到 (Intercept) ?如果是这样的话,这应该有效

    library(tidyverse)
    
    min_to_base <- function(df, cols){
      mins <- lapply(df[cols], min)
      df[cols] <- df[cols] - mins
      df['(Intercept)'] <- df['(Intercept)'] + do.call(sum, mins)
      df
    }
    
    impacts %>% 
      t %>% 
      as_tibble(rownames = 'dt') %>% 
      min_to_base(c('x1', 'x2'))
    
    
    #   dt         `(Intercept)`     x1     x2     x3
    #   <chr>              <dbl>  <dbl>  <dbl>  <dbl>
    # 1 2016-01-01          19.9 0      0.0362 -0.217
    # 2 2016-01-02          19.9 0.140  0.0562 -0.192
    # 3 2016-01-03          19.9 0.137  0.254  -0.269
    # 4 2016-01-04          19.9 0.129  0      -0.161
    # 5 2016-01-05          19.9 0.0639 0.203  -0.152
    # 6 2016-01-06          19.9 0.0175 0.0162 -0.197
    

    下面是一种让函数表现为NSE的黑客方法(与上面的结果相同)。

    min_to_base <- function(df, ...){
      cols <- as.character(ensyms(...))
      mins <- lapply(df[cols], min)
      df[cols] <- df[cols] - mins
      df['(Intercept)'] <- df['(Intercept)'] + do.call(sum, mins)
      df
    }
    
    impacts %>% 
      t %>% 
      as_tibble(rownames = 'dt') %>% 
      min_to_base(x1, x2)
    

    使用的数据:

    impacts <- 
    structure(list(`2016-01-01` = c(19.612765930918, 0.0139082609319898, 
    0.298043103003794, -0.217012113254805), `2016-01-02` = c(19.612765930918, 
    0.153780074988214, 0.317999312583603, -0.192164881529573), `2016-01-03` = c(19.612765930918, 
    0.150571795109967, 0.515644453462975, -0.269251568581305), `2016-01-04` = c(19.612765930918, 
    0.142512722884255, 0.261814150174792, -0.160625206980914), `2016-01-05` = c(19.612765930918, 
    0.0778498178207942, 0.464855455837326, -0.15224027496774), `2016-01-06` = c(19.612765930918, 
    0.0314062544574153, 0.278014325308919, -0.19657100740319)), class = "data.frame", row.names = c("(Intercept)", 
    "x1", "x2", "x3"))