【问题标题】:Dividing across multiple columns in r using mutate_at call使用 mutate_at 调用在 r 中划分多个列
【发布时间】:2017-11-22 16:52:12
【问题描述】:

我有一个看起来像这样的数据框(我们称之为每月平均值)...

month_year       product_key_1      product_key_2        product_key_3        product_key_4
2014-08          NA                 NA                   NA                   50
2014-09          NA                 NA                   NA                   NA
2014-10          NA                 NA                   149                  NA
2014-11          NA                 40                   116.81               NA
2014-12          NA                 43                   117                  NA
2015-01          65                 NA                   117                  NA
2015-02          65                 NA                   300                  60
2015-03          65                 NA                   NA                   60
2015-04          NA                 NA                   NA                   70
2015-05          NA                 NA                   NA                   NA
2015-06          NA                 NA                   NA                   NA

但我有数千行和几个月的时间。我想做的是创建价格亲戚,但使用前一个月(不是一月的基准月)。因此,以 product_key_3 为例,我将 116.81/149 作为 2014-09 的相对价格,将 117/116.81 作为 2014-10 的相对价格,依此类推。如果我想要的上一个单元格中有 NA,或者在整个几个月中只观察到该产品的一个价格,我希望价格相对是(使用 product_key_2)作为示例,2014-11 为 40/40。

我想要的输出看起来像这样:

          month_year       pr_product_1      pr_product_2        pr_product_3   pr_product_4

            2014-08          NA                 NA                   NA                 1
            2014-09          NA                 NA                   NA                 NA
            2014-10          NA                 NA                   1                  NA
            2014-11          NA                 1                    0.7839             NA
            2014-12          NA                 1.075                1.0016             NA
            2015-01          1                  NA                   1                  NA
            2015-02          1                  NA                   2.5641             1
            2015-03          1                  NA                   NA                 1
            2015-04          NA                 NA                   NA                 1.16
            2015-05          NA                 NA                   NA                 NA
            2015-06          NA                 NA                   NA                 NA

我已经设法通过使用以下方法完成了我上面解释过的事情: monthlyaveragestest <- monthlyaverages %>% mutate_at(.vars=vars(matches("product", ignore.case = FALSE)), .funs=funs(lag(lead(.)/.,)))

但现在我想做一些类似的事情,而是跨列划分而不是跨行划分。我知道可能有一个快速修复,但我已经尝试了此代码的许多变体,但似乎无法让它工作,我找不到与我正在尝试做的类似的另一个问题。

任何帮助将不胜感激。您可以使用以下方法重新创建我的示例数据集:

date <- c(2014-08, 2014-09, 2014-10, 2014-11, 2014-12, 2015-01, 2015-02, 2015-03, 2015-04, 2015-05, 2015-06)
product_key_1 <- c(NA, NA, NA, NA, NA, 65, 65, 65, NA, NA, NA)                    
product_key_2 <- c(NA, NA, NA, 40, 43, NA, NA, NA, NA, NA, NA)
product_key_3 <- c(NA, NA, 149, 116.81, 117, 117, 300, NA, NA, NA, NA)
product_key_4 <- c(50, NA, NA, NA, NA, NA, 60, 60, 70, NA, NA)
monthlyaverages <- data.frame(date, product_key_1, product_key_2, product_key_3, product_key_4)

如果所有这些都有意义,请告诉我,如果我能让它更清楚一些。谢谢。

【问题讨论】:

    标签: r dataframe dplyr data-manipulation


    【解决方案1】:

    我想如果你把你的数据转换成长格式,然后使用lag()来划分列,你应该接近:

    library(tidyverse)
    
    monthlyaverages %>% 
        # turn it into long format
        gather(key, val, -month_year) %>%
        # insert a seperator to make it easier to split out the unique column name
        mutate(key = str_replace(key, "_(\\d+)", ";\\1") ) %>% 
        # split out the column name
        separate(key, c("key2", "type"), sep = ";") %>% 
        # sort by date, then by type
        group_by(month_year) %>%
        arrange(type) %>% 
        # divide the previous value by the current value, defaulting to 1 when val is NA
        # not sure exactly what you want--maybe you'll need to swap lag(val) and val
        mutate(  newval = lag(val)/coalesce(val,1)  ) %>% 
        ungroup() %>%
        # drop the unnecssary variables
        select(month_year, type, newval) %>% 
        # spread out the new variables
        spread(type, newval, sep = "div_")
    

    稍后,您可以使用 left_join() 在月份之前将其加入到 monthlyaverages

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      相关资源
      最近更新 更多