我有一个看起来像这样的数据框(让我们称之为monthlyaverages)......
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的价格相对而且相对于2014-10的价格为117 / 116.81,依此类推。如果我想要的前一个单元格中有NA,或者在这几个月内只有一个价格观察到该产品,我希望价格相对于(使用product_key_2)作为示例,2014/11年为40/40。 / p>
我想要的输出看起来像这样:
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)
如果所有这些都有意义,请告诉我,如果我能说清楚的话。感谢。
答案 0 :(得分: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()
通过month_year将其加入monthlyaverages
。