R:是否有等价于 diff(x) 的除法?
R: is there an equivalent of diff(x) for dividing?
我正在处理财务数据的数据帧,我想在其中获取行之间的差异,以及行之间的 "change"。不同的是,任务很简单,只需:
apply(df, MARGIN=2, FUN=function(x) diff(x))
当我想要更改而不是差异时,我的问题就出现了。也就是说,在数据框的每一列中,我想迭代地将列的下一个元素除以前一个元素,然后减去一个。我这样做的快速而肮脏的方法如下:
apply(df, MARGIN=2, FUN=function(x) x[2:length(x)]/x[1:length(x)-1]-1)
但我想知道是否有一个功能可以为我做这件事?
编辑:小可重现,按要求:
数据<-data.frame(c(1,2,4,15),c(2,1,5,8))
上面我自己的代码片段的输出(也是预期的):
我不知道基本的 R 函数可以完全做到这一点,但外部包中有不同的 lag
/lead
函数。例如,您可以这样使用 dplyr
:
> mutate_each(head(iris[-5]), funs(./lag(.)-1))
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#1 NA NA NA NA
#2 -0.03921569 -0.14285714 0.00000000 0
#3 -0.04081633 0.06666667 -0.07142857 0
#4 -0.02127660 -0.03125000 0.15384615 0
#5 0.08695652 0.16129032 -0.06666667 0
#6 0.08000000 0.08333333 0.21428571 1
对比自己的功能:
> apply(head(iris[-5]), MARGIN=2, FUN=function(x) x[2:length(x)]/x[1:length(x)-1]-1)
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#2 -0.03921569 -0.14285714 0.00000000 0
#3 -0.04081633 0.06666667 -0.07142857 0
#4 -0.02127660 -0.03125000 0.15384615 0
#5 0.08695652 0.16129032 -0.06666667 0
#6 0.08000000 0.08333333 0.21428571 1
您可以将其放入自定义函数中并使用:
f <- function(., n = 1L, default = NA) ./dplyr::lag(., n = n, default = default) -1
mutate_each(head(iris[-5]), funs(f))
这是 data.table
中带有 shift
的选项
library(data.table)
as.data.table(head(iris))[, lapply(.SD, function(x)
x/shift(x)-1), .SDcols=1:4]
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#1: NA NA NA NA
#2: -0.03921569 -0.14285714 0.00000000 0
#3: -0.04081633 0.06666667 -0.07142857 0
#4: -0.02127660 -0.03125000 0.15384615 0
#5: 0.08695652 0.16129032 -0.06666667 0
#6: 0.08000000 0.08333333 0.21428571 1
这里有几种方法。第一个 returns 是数据框,第二个是矩阵,最后一个是动物园对象。前两个不使用任何包。
> data[-1,] / data[-nrow(data), ] - 1
c.1..2..4..15. c.2..1..5..8.
2 1.00 -0.5
3 1.00 4.0
4 2.75 0.6
> exp(diff(log(as.matrix(data)))) - 1
c.1..2..4..15. c.2..1..5..8.
[1,] 1.00 -0.5
[2,] 1.00 4.0
[3,] 2.75 0.6
> library(zoo)
> diff(as.zoo(data), arithmetic = FALSE) - 1
c.1..2..4..15. c.2..1..5..8.
2 1.00 -0.5
3 1.00 4.0
4 2.75 0.6
使用对数转换exp(diff(log(x)))-1)
:
> apply(data, MARGIN=2, FUN=function(x) exp(diff(log(x)))-1)
c.1..2..4..15. c.2..1..5..8.
[1,] 1.00 -0.5
[2,] 1.00 4.0
[3,] 2.75 0.6
最简单的方法:
x <- c(10, 20, 30, 40, 50)
x/lag(x)
# [1] NA 2.000000 1.500000 1.333333 1.250000
我正在处理财务数据的数据帧,我想在其中获取行之间的差异,以及行之间的 "change"。不同的是,任务很简单,只需:
apply(df, MARGIN=2, FUN=function(x) diff(x))
当我想要更改而不是差异时,我的问题就出现了。也就是说,在数据框的每一列中,我想迭代地将列的下一个元素除以前一个元素,然后减去一个。我这样做的快速而肮脏的方法如下:
apply(df, MARGIN=2, FUN=function(x) x[2:length(x)]/x[1:length(x)-1]-1)
但我想知道是否有一个功能可以为我做这件事?
编辑:小可重现,按要求:
数据<-data.frame(c(1,2,4,15),c(2,1,5,8))
上面我自己的代码片段的输出(也是预期的):
我不知道基本的 R 函数可以完全做到这一点,但外部包中有不同的 lag
/lead
函数。例如,您可以这样使用 dplyr
:
> mutate_each(head(iris[-5]), funs(./lag(.)-1))
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#1 NA NA NA NA
#2 -0.03921569 -0.14285714 0.00000000 0
#3 -0.04081633 0.06666667 -0.07142857 0
#4 -0.02127660 -0.03125000 0.15384615 0
#5 0.08695652 0.16129032 -0.06666667 0
#6 0.08000000 0.08333333 0.21428571 1
对比自己的功能:
> apply(head(iris[-5]), MARGIN=2, FUN=function(x) x[2:length(x)]/x[1:length(x)-1]-1)
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#2 -0.03921569 -0.14285714 0.00000000 0
#3 -0.04081633 0.06666667 -0.07142857 0
#4 -0.02127660 -0.03125000 0.15384615 0
#5 0.08695652 0.16129032 -0.06666667 0
#6 0.08000000 0.08333333 0.21428571 1
您可以将其放入自定义函数中并使用:
f <- function(., n = 1L, default = NA) ./dplyr::lag(., n = n, default = default) -1
mutate_each(head(iris[-5]), funs(f))
这是 data.table
shift
的选项
library(data.table)
as.data.table(head(iris))[, lapply(.SD, function(x)
x/shift(x)-1), .SDcols=1:4]
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#1: NA NA NA NA
#2: -0.03921569 -0.14285714 0.00000000 0
#3: -0.04081633 0.06666667 -0.07142857 0
#4: -0.02127660 -0.03125000 0.15384615 0
#5: 0.08695652 0.16129032 -0.06666667 0
#6: 0.08000000 0.08333333 0.21428571 1
这里有几种方法。第一个 returns 是数据框,第二个是矩阵,最后一个是动物园对象。前两个不使用任何包。
> data[-1,] / data[-nrow(data), ] - 1
c.1..2..4..15. c.2..1..5..8.
2 1.00 -0.5
3 1.00 4.0
4 2.75 0.6
> exp(diff(log(as.matrix(data)))) - 1
c.1..2..4..15. c.2..1..5..8.
[1,] 1.00 -0.5
[2,] 1.00 4.0
[3,] 2.75 0.6
> library(zoo)
> diff(as.zoo(data), arithmetic = FALSE) - 1
c.1..2..4..15. c.2..1..5..8.
2 1.00 -0.5
3 1.00 4.0
4 2.75 0.6
使用对数转换exp(diff(log(x)))-1)
:
> apply(data, MARGIN=2, FUN=function(x) exp(diff(log(x)))-1)
c.1..2..4..15. c.2..1..5..8.
[1,] 1.00 -0.5
[2,] 1.00 4.0
[3,] 2.75 0.6
最简单的方法:
x <- c(10, 20, 30, 40, 50)
x/lag(x)
# [1] NA 2.000000 1.500000 1.333333 1.250000