在数据框的每一行中应用条件函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在数据框的每一行中应用条件函数相关的知识,希望对你有一定的参考价值。
我是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”,请执行因子1 /因子1(1天滞后)*因子2 +扩散,如果组不是“a”,则不添加扩散。
由于你正在调整这个群体,这是by
(基地R),dplyr::group_by
或data.table
的x[,,by=]
的一个很好的例子。
这三个方程实际上是相同的,利用(Group[1] == "a")
在被数字乘以时从logical
强制到numeric
的事实;因为FALSE
转换为0,然后有效禁用添加Spread
。
Base
我在这里使用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
,有一些奇特的by
特定的格式,所以你可以把它当作有效的基础-R方式组合它们:
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
另一方面,许多人发现data.table
更好,因为从就地修改中获得了效率(大多数R的操作都是写时复制,这意味着某些操作会在每次更改时重新复制对象或其中的一部分)。
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
“就地”部分在这里的第二行显而易见,似乎[
操作应该只返回一个子集或某些数据...但在这种情况下使用:=
导致列被创建(或改变了就地。
以上是关于在数据框的每一行中应用条件函数的主要内容,如果未能解决你的问题,请参考以下文章