将R函数应用于行,具体取决于其他列中的值 [英] Apply R-function to rows depending on value in other column

查看:79
本文介绍了将R函数应用于行,具体取决于其他列中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下功能,可以在一列中为变量建立股票效应.变量会在B列中创建一个值,该值会在ColumnA中获得该值,并从B列中的上一个观察值中结转(例如0.5).

I have the following function to build a stock effect for a variable in one column. The variable creates a value in Column B that takes the value in ColumnA and adds a carry over (like e.g. 0.5) from the previous observation in Column B.

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
}

我的问题是,现在我有了一个面板数据集,该数据集在一列中观察到了许多不同的情况.每个案例都有一个特定的指示符(数字).数据如下:

My problem is now that I have a panel data set that has in one column observations for many different cases. Each case has a specific indicator (numeric). Data looks like:

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

我现在希望将函数应用于所有观察(时间)的每种情况(指标).

I now want the function to be applied to each case (Indicator) for all observations (Time).

任何想法如何实现这一目标?输出应如下所示:

Any idea how to achieve this? The Output should then look like:

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

任何帮助或支持都将受到高度赞赏!

Any help or support is highly appreciated!

非常感谢!

推荐答案

这是替代的无循环/功能编程解决方案.我们将使用 Reduce()函数,该函数将二进制函数应用于向量中的每对项目.

Here is an alternative loop-free/functional programming solution. We are going to use the Reduce() function which applies a binary function over every pair of items in a vector.

例如, Reduce(`+`,xs)计算向量中的值之和.如果设置 accumulate = TRUE ,我们将获得滚动/累积和.

For example, Reduce(`+`, xs) computes the sum of values in vector. If we set accumulate = TRUE, we get a rolling/cumulative sum.

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().)

(The purrr package separates these two behaviors into different functions: reduce() and accumulate().)

我们可以使用 Reduce()来实现结转/缩放功能.首先,定义一个适用于一对值的函数,然后使用 Reduce()对其进行滚动版本.

We can use Reduce() to implement the carry-over/scaling function. First, define a function that works on a pair of values, then use Reduce() to perform a rolling version of it.

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并将此滚动功能应用于每个指标组.

Now, we can use dplyr and apply this rolling function to each indicator group.

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

这篇关于将R函数应用于行,具体取决于其他列中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆