r - add_row 并做一些计算

标签 r dplyr

假设我有一个如下所示的 data.frame:

df <- data.frame(group = c("group1","group1", "group2", "group2"), 
                 year = c(2000, 2001, 2000, 2001), 
                 value = c(10, 13, 2, 5))

我想按每个组分组,然后添加一行,然后对第 3 列进行计算。因此,例如,新数据框看起来像这样(计算只是 value(-1) +值(-2))

df <- data.frame(group = c("group1","group1", "group1", "group2", "group2", "group2"), 
                 year = c(2000, 2001, 2002, 2000, 2001, 2002), 
                 value = c(10, 13, 23, 2, 5, 7))

我试过使用 dplyr,但我似乎无法弄明白。所以我对任何解决方案都持开放态度,尽管如果有一个 dplyr 解决方案那就太好了!

此外,我希望能够将这十个时期计算到 future ,因此年份将是最终 data.frame 中从 2000 年到 2011 年的序列。

最佳答案

这是一种类似于斐波那契的计算,使用 for 循环编写起来非常简单,而使用矢量化操作就没那么简单了。在 R 中应谨慎使用 for 循环,因为不正确地使用它们会使您的代码慢得惊人,但是如果您通过使用 tidyr::complete 扩展 data.frame 来预分配内存> 事先,您可以编写一个函数来轻松包含循环:

library(tidyverse)

df <- data.frame(group = c("group1","group1", "group2", "group2"), 
                 year = c(2000, 2001, 2000, 2001), 
                 value = c(10, 13, 2, 5))

fibonacci <- function(x){
    for(i in seq(3, length(x))){
        x[i] <- x[i-1] + x[i-2]
    }
    x
}

df2 <- df %>% 
    group_by(group) %>% 
    complete(year = 2000:2005) %>% 
    mutate(value = fibonacci(value))

df2
#> # A tibble: 12 x 3
#> # Groups:   group [2]
#>     group  year value
#>    <fctr> <dbl> <dbl>
#>  1 group1  2000    10
#>  2 group1  2001    13
#>  3 group1  2002    23
#>  4 group1  2003    36
#>  5 group1  2004    59
#>  6 group1  2005    95
#>  7 group2  2000     2
#>  8 group2  2001     5
#>  9 group2  2002     7
#> 10 group2  2003    12
#> 11 group2  2004    19
#> 12 group2  2005    31

如果您想避免循环和矢量化,请使用斐波那契数列的公式表达式。来自 Wikipedia ,

fibonacci2 <- function(u0, u1, n){
    phi <- (1 + sqrt(5)) / 2
    psi <- 1 - phi
    a <- (u1 - u0 * psi) / sqrt(5)
    b <- (u0 * phi - u1) / sqrt(5)
    a * phi^n + b * psi^n
}

df3 <- df %>% 
    group_by(group) %>% 
    complete(year = 2000:2005) %>% 
    mutate(value = fibonacci2(value[1], value[2], seq.int(0L, length(value) - 1)))

df3
#> # A tibble: 12 x 3
#> # Groups:   group [2]
#>     group  year value
#>    <fctr> <dbl> <dbl>
#>  1 group1  2000    10
#>  2 group1  2001    13
#>  3 group1  2002    23
#>  4 group1  2003    36
#>  5 group1  2004    59
#>  6 group1  2005    95
#>  7 group2  2000     2
#>  8 group2  2001     5
#>  9 group2  2002     7
#> 10 group2  2003    12
#> 11 group2  2004    19
#> 12 group2  2005    31

有些奇怪(可能是由于适当的预分配和 R 为循环添加的 JIT 编译),两者之间几乎没有时间差异。基准测试很棘手,因为该系列往往会超过 .Machine$double.xmax 并在大约第 1475 项时转向 Inf,但每个方法都会在新输入上复制到 1,475,000 次计算,

microbenchmark::microbenchmark(
    fibonacci = replicate(1000, {
        x <- double(1475); 
        x[1:2] <- rnorm(2); 
        fibonacci(x)
    }),
    fibonacci2 = replicate(1000, {
        x <- double(1475); 
        x[1:2] <- rnorm(2); 
        fibonacci2(x[1], x[2], seq.int(0L, length(x) - 1L))
    })
)
#> Unit: milliseconds
#>        expr      min       lq     mean   median       uq      max neval
#>   fibonacci 249.4110 255.9866 264.2625 261.6491 272.0018 295.3266   100
#>  fibonacci2 202.3588 209.0647 219.0509 214.2429 223.5476 375.7604   100

关于r - add_row 并做一些计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44961933/

相关文章:

r - 添加 geom_smooth 时如何为图例中的点获得正确的形状和颜色?

r - 为原始函数的隐式 S4 泛型添加额外参数

r - 如何将集合变成集合成员的指标?

r - 在函数内部使用 dplyr 时出错

r - 在 ggbiplot 中指定箭头(线段)的颜色、透明度和位置

r - 检查 NaN 后如何用其日志替换数据帧中的所有值

html - 在 Markdown 中制作格式良好的表格 : knitr not compiling stargazer>html table

r - 在 R 中的 For 循环中执行特定于案例的编辑

r - 对具有相似名称的多组列使用相同的 mutate

r - dplyr 折叠时间段