scala> class SubClass(d: Engage, p: Event) extends BaseSchema(d, p)
defined class SubClass
我想每年计算前7个值中前5个值的平均值。例如 第一个平均值将是1977年的平均值,其中包括从1970年到1976年的最佳5年平均值。 对于1978年,平均值将是1971-1977年的前5个值。 同样,对于2018年,平均值将是2011年至2017年的前5个值
我从SO中获得以下代码来完成这项工作。
dat <- structure(list(yearRef = c(1970, 1971, 1972, 1973, 1974, 1975,
1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986,
1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018),
value = c(0.761253538863966, 0.778365700864592, 0.748473422160476,
0.790408287413012, 0.726707786670043, 0.80587461240495, 0.81582881742434,
0.914998995290579, 0.903241004636529, 0.883446087736501,
0.878399385374308, 0.790239960507709, 0.853841173129717,
0.972923769177295, 0.899133969911117, 0.865840008976815,
0.85942147306247, 0.9471790327507, 0.905362802563981, 0.91644169495142,
0.985789564141214, 0.978212191208007, 0.885157529562834,
1.01638026873823, 1.02702020472382, 0.944421276774342, 0.979439113456467,
0.951183598644539, 1.12054063623421, 1.00767230122493, 1.02132151007705,
0.95649988168142, 0.928385199359045, 1.05071183719421, 1.11654102944792,
0.910601547182633, 0.936460862711605, 1.2398210426787, 0.979036947391532,
1.09931214756341, 1.12206830109171, 0.997384903912461, 1.07413151131128,
0.967026290186151, 1.04921352764649, 1.08746580600605, 1.02444885186573,
1.14604631626466, 1.06449109417896)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -49L))
尽管新列 library(data.table)
library(zoo)
setDT(dat)
dat[, mean.val:= if (.N > 6)
rollapplyr(value, 7,function(x) mean(tail(sort(x), 5)), fill = NA)
else mean(value)]
中的第一个值正确,但应将其分配给具有以下内容的行:
1977年,但已分配给1976年。
答案 0 :(得分:3)
您要处理 PRIOR 7点,而不是当前点的7点。为此,请使用list(-(1:7))
的宽度。也就是说,在处理数据时使用-1到-7的偏移量。有关指定?rollapply
自变量的更多信息,请参见width
。
与需要忽略所需偏移量然后在以后进行修正的方法相比,此(1)更直接地指定了意图,使其更易于理解,并且(2)仅使用您已经在使用的软件包(3)紧凑地表达了解决方案(4)仅更改一个参数即可保留您的解决方案。
dat[, mean.val:= if (.N > 6)
rollapply(value, list(-(1:7)), function(x) mean(tail(sort(x), 5)), fill = NA)
else mean(value)]
答案 1 :(得分:2)
如果唯一的问题是应将值向下移动1行,则可以使用shift
来解决此问题。
dat[, mean.val := shift(mean.val)]
仅供参考,如果您使用的是版本大于等于1.12.4 data.table的数据,则您不需要Zoo,可以使用data.table::frollapply
。
dat[, mean.val2 :=
shift(frollapply(value, 7, function(x) mean(tail(sort(x), 5))))]
dat[, all.equal(mean.val, mean.val2)] #TRUE
答案 2 :(得分:0)
我认为您可以使用出色的tsibble程序包实现出色的滚动功能,然后使用Lead函数来替换结果
library(tidyverse)
dat <- structure(list(yearRef = c(1970, 1971, 1972, 1973, 1974, 1975,
1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986,
1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018),
value = c(0.761253538863966, 0.778365700864592, 0.748473422160476,
0.790408287413012, 0.726707786670043, 0.80587461240495, 0.81582881742434,
0.914998995290579, 0.903241004636529, 0.883446087736501,
0.878399385374308, 0.790239960507709, 0.853841173129717,
0.972923769177295, 0.899133969911117, 0.865840008976815,
0.85942147306247, 0.9471790327507, 0.905362802563981, 0.91644169495142,
0.985789564141214, 0.978212191208007, 0.885157529562834,
1.01638026873823, 1.02702020472382, 0.944421276774342, 0.979439113456467,
0.951183598644539, 1.12054063623421, 1.00767230122493, 1.02132151007705,
0.95649988168142, 0.928385199359045, 1.05071183719421, 1.11654102944792,
0.910601547182633, 0.936460862711605, 1.2398210426787, 0.979036947391532,
1.09931214756341, 1.12206830109171, 0.997384903912461, 1.07413151131128,
0.967026290186151, 1.04921352764649, 1.08746580600605, 1.02444885186573,
1.14604631626466, 1.06449109417896)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -49L))
complex_function <- . %>%
sort %>%
tail(.,5) %>%
mean
dat %>%
mutate(roll_avg = tsibble::slide_dbl(.x = value,.f = complex_function,.size = 7),
roll_avg2 = lag(roll_avg))
#> # A tibble: 49 x 4
#> yearRef value roll_avg roll_avg2
#> <dbl> <dbl> <dbl> <dbl>
#> 1 1970 0.761 NA NA
#> 2 1971 0.778 NA NA
#> 3 1972 0.748 NA NA
#> 4 1973 0.790 NA NA
#> 5 1974 0.727 NA NA
#> 6 1975 0.806 NA NA
#> 7 1976 0.816 0.790 NA
#> 8 1977 0.915 0.821 0.790
#> 9 1978 0.903 0.846 0.821
#> 10 1979 0.883 0.865 0.846
#> # … with 39 more rows
由reprex package(v0.3.0)于2020-01-14创建
答案 3 :(得分:0)
这个简单的for循环解决了这个问题:
dat$mean.val = NA
for(i in 8:nrow(dat))
{
dat$mean.val[i] = mean(sort(dat$value[(i-7):(i-1)],decreasing = TRUE)[1:5])
}