我是R语言的新手,并且正在为此看起来像这样的df挣扎:
Date Group Factor 1 Factor 2 Spread
2019-04-01 a 1.01 1.011 0.01
2019-04-02 a 1.02 1.012 0.02
2019-04-03 a 1.03 1.013 0.03
2019-04-01 b 1.005 1.004 0.01
2019-04-02 b 1.0051 1.0041 0.02
2019-04-03 b 1.0052 1.0042 0.03
我想验证每行中的每个组,如果结果是“ a”组,则执行Factor1 / Factor1(1天滞后)* Factor2 +价差,如果不是“ a”组,则不添加价差
答案 0 :(得分:0)
由于您以小组为条件,所以这是by
(以R为底),dplyr::group_by
或data.table
的{{1}}的一个很好的例子。
等式实际上在所有三个等式中都是相同的,这是利用x[,,by=]
乘以一个数字时将从(Group[1] == "a")
强制到logical
的事实。因为numeric
转换为0,所以实际上禁止添加FALSE
。
我在这里使用Spread
来使内部结构更具可读性,但这不是必须的(在这种情况下,您需要在所有变量名之前加within
)
可以使用x$
(即使您不使用此包的其余部分)或许多其他方法来完成滞后。我发现dplyr::lag
在这样的应用程序中不是最直观的,但是我敢肯定有人会建议将其合并到答案中的方法。使用stats::lag
可确保我们不会引入其他组的数据或估算数据,因为我们没有引入组第一行的价值。最后,c(NA, ...)
返回向量/列表的第一个元素,而head(..., n = 1)
(负数)返回除最后一个以外的所有元素。
head(..., n = -1)
这实际上只是一个newx <- by(x, x$Group, function(y) {
within(y, {
NewVal = Factor2 * Factor1 / c(NA, head(Factor1, n=-1)) + (Group[1] == "a") * Spread
})
})
newx
# x$Group: a
# Date Group Factor1 Factor2 Spread NewVal
# 1 2019-04-01 a 1.01 1.011 0.01 NA
# 2 2019-04-02 a 1.02 1.012 0.02 1.042020
# 3 2019-04-03 a 1.03 1.013 0.03 1.052931
# -------------------------------------------------------
# x$Group: b
# Date Group Factor1 Factor2 Spread NewVal
# 4 2019-04-01 b 1.0050 1.0040 0.01 NA
# 5 2019-04-02 b 1.0051 1.0041 0.02 1.0042
# 6 2019-04-03 b 1.0052 1.0042 0.03 1.0043
,具有一些list
特定的格式,因此您可以将其视为以有效的base-R方式将它们组合在一起的方式:
by
do.call("rbind.data.frame", c(newx, stringsAsFactors = FALSE))
# Date Group Factor1 Factor2 Spread NewVal
# a.1 2019-04-01 a 1.0100 1.0110 0.01 NA
# a.2 2019-04-02 a 1.0200 1.0120 0.02 1.042020
# a.3 2019-04-03 a 1.0300 1.0130 0.03 1.052931
# b.4 2019-04-01 b 1.0050 1.0040 0.01 NA
# b.5 2019-04-02 b 1.0051 1.0041 0.02 1.004200
# b.6 2019-04-03 b 1.0052 1.0042 0.03 1.004300
许多人都找到了dplyr
行的软件包以直观地阅读。
tidyverse
library(dplyr)
x %>%
group_by(Group) %>%
mutate(NewVal = Factor2 * Factor1 / lag(Factor1) + (Group[1] == "a") * Spread) %>%
ungroup()
# # A tibble: 6 x 6
# Date Group Factor1 Factor2 Spread NewVal
# <chr> <chr> <dbl> <dbl> <dbl> <dbl>
# 1 2019-04-01 a 1.01 1.01 0.01 NA
# 2 2019-04-02 a 1.02 1.01 0.02 1.04
# 3 2019-04-03 a 1.03 1.01 0.03 1.05
# 4 2019-04-01 b 1.00 1.00 0.01 NA
# 5 2019-04-02 b 1.01 1.00 0.02 1.00
# 6 2019-04-03 b 1.01 1.00 0.03 1.00
另一方面,许多人发现data.table
更好,因为就地修改可提高效率(R的大多数操作都是写时复制,这意味着某些操作会重新复制对象或对象的一部分每次更改)。
data.table
“就地”部分在第二行很明显,似乎library(data.table)
X <- as.data.table(x)
X[, NewVal := Factor2 * Factor1 / shift(Factor1) + (Group[1] == "a") * Spread, by = "Group"]
X
# Date Group Factor1 Factor2 Spread NewVal
# 1: 2019-04-01 a 1.0100 1.0110 0.01 NA
# 2: 2019-04-02 a 1.0200 1.0120 0.02 1.042020
# 3: 2019-04-03 a 1.0300 1.0130 0.03 1.052931
# 4: 2019-04-01 b 1.0050 1.0040 0.01 NA
# 5: 2019-04-02 b 1.0051 1.0041 0.02 1.004200
# 6: 2019-04-03 b 1.0052 1.0042 0.03 1.004300
操作应该只返回一个子集或某些数据……但在这种情况下使用{{ 1}}导致就地创建(或更改)列。