2016-11-24 90 views
0

我有以下函数为一列中的变量构建股票效果。变量创建在列B,取入ColumnA的值和从先前观察在列B增加了一个结转(如例如0.5)的值根据其他列中的值对行应用R函数

constructZ <- function(lag, N) { 
    r <- lag^(seq_len(N)-1) 
    m <- matrix(rep(r,N),nrow=N) 
    z <- matrix(0,nrow=N,ncol=N) 
    z[lower.tri(z,diag=TRUE)] <- m[row(m) <= (N+1-col(m))] 
    z 
} 

我的问题是现在,我有一个面板数据集在一列中有许多不同情况的观察结果。每个案例都有一个特定的指标(数字)。数据是这样的:

ColumnA  Indicator   Time 
1   1     1 
0   1     2 
0   1     3 
4   2     1 
5   2     2 
0   2     3 
4   3     1 
0   3     2 
2   3     3 

我现在想要的功能,适用于各种情况下(指标)的所有观测值(时间)。

任何想法如何实现这一目标?输出应该看起来像:

ColumnA  Indicator   Time   ColumnB 
    1   1     1   1 
    0   1     2   0.5 
    0   1     3   0.25 
    4   2     1   4 
    5   2     2   7 
    0   2     3   3.5 
    4   3     1   4 
    0   3     2   2 
    2   3     3   3 

任何帮助或支持,高度赞赏!

非常感谢提前!

+2

滞后和N的值会得到预期的输出是什么? – akrun

+0

告诉我,如果我已经明白了:columnB [i] = columnA + columnB [i-1] * something? :) – Ale

回答

0

这是我的代码。

library(dplyr) # Optional, but makes code cleaner 
raw = data.frame(ColumnA = 
        c(1, 0, 0, 4, 5, 0, 4, 0, 2), 
       Indicator = 
        rep(x = 1:3, each = 3), 
       Time = 1:3) 
factor = 0.5 
loop = function(vec) { 
    length = length(x = vec) 
    if (length == 1) { 
    return(vec) 
    } 
    if (length == 2) { 
    return(vec + c(0, vec[2] * factor)) 
    } 
    for (idx in 2:length) { 
    vec[idx] = vec[idx] + vec[idx - 1] * factor 
    } 
    return(vec) 
} 
output = raw %>% 
    mutate(ColumnB = 
      tapply(X = ColumnA, 
        INDEX = Indicator, 
        FUN = loop) %>% 
    unlist()) 
output 
0

这是另一种无环路/功能性编程解决方案。我们将使用Reduce()函数,该函数将矢量中的每对项应用二元函数。例如,Reduce(`+`, xs)计算向量中的值的总和。如果我们设置accumulate = TRUE,我们得到滚动/累计和。

Reduce(`+`, 1:6) 
#> [1] 21 

# What Reduce is doing here, basically 
((((((1) + 2) + 3) + 4) + 5) + 6) 
#> [1] 21 

# Keep each intermediate sum 
Reduce(`+`, 1:6, accumulate = TRUE) 
#> [1] 1 3 6 10 15 21 

(该purrr包这两种行为分成不同的功能:reduce()accumulate()。)

我们可以使用Reduce()实现结转/缩放功能。首先,定义一个对一对值起作用的函数,然后使用Reduce()来执行它的滚动版本。

rolling_scale <- function(xs, scale_factor) { 
    scale_pair <- function(x1, x2) x2 + scale_factor * x1 
    Reduce(scale_pair, xs, accumulate = TRUE) 
} 

rolling_scale(c(4, 5, 0), .5) 
#> [1] 4.0 7.0 3.5 

现在,我们可以使用dplyr并将此滚动函数应用于每个指标组。

library(dplyr) 

raw <- data.frame(
    ColumnA = c(1, 0, 0, 4, 5, 0, 4, 0, 2), 
    Indicator = rep(x = 1:3, each = 3), 
    Time = 1:3) 

raw %>% 
    group_by(Indicator) %>% 
    mutate(ColumnB = rolling_scale(ColumnA, .5)) %>% 
    ungroup() 
#> # A tibble: 9 × 4 
#> ColumnA Indicator Time ColumnB 
#>  <dbl>  <int> <int> <dbl> 
#> 1  1   1  1 1.00 
#> 2  0   1  2 0.50 
#> 3  0   1  3 0.25 
#> 4  4   2  1 4.00 
#> 5  5   2  2 7.00 
#> 6  0   2  3 3.50 
#> 7  4   3  1 4.00 
#> 8  0   3  2 2.00 
#> 9  2   3  3 3.00