我可以对矢量执行滚动划分,我可以获取数据,然后滞后相同的数据并执行除法:
# Dummy Data
sample <- c(4,5,6,7,8,4,2,6,5,4,3,2,1,2,3,4,5,6)
lagSam <- lag(sample) # Lag by 1
output <- sample / lagSam # Perform division
sample.df <- data.frame(sample, desired = output)
with the desired output:
sample desired
1 4 NA
2 5 1.2500000
3 6 1.2000000
4 7 1.1666667
5 8 1.1428571
6 4 0.5000000
7 2 0.5000000
8 6 3.0000000
9 5 0.8333333
10 4 0.8000000
11 3 0.7500000
12 2 0.6666667
13 1 0.5000000
14 2 2.0000000
15 3 1.5000000
16 4 1.3333333
17 5 1.2500000
18 6 1.2000000
我的问题是,我如何在数据框架上做同样的事情?我有超过100列,需要对每个列进行滚动划分。我正在尝试编写一个函数并使用roll apply:
# My attempt
division <- function(x) {
#tail(x,1) / head(x,1)
x / lag(x)
}
rollapplyr(sample.df$sample, 1, division, fill = NA)
我试图用头部和尾部滞后,然后再次使用x /滞后x。
两种结果都会产生NA。
答案 0 :(得分:2)
我经常发现我想要dplyr::lag
行为,但当stats::lag
返回类似tsp
的对象时,我会感到吃惊。
您已关闭tail/head
功能。使用否定n
:
n: a single integer. If positive, size for the resulting object: number of elements for a vector (including lists), rows for a matrix or data frame or lines for a function. If negative, all but the 'n' last/first number of elements of 'x'.
c(NA, tail(sample.df$sample,n=-1) / head(sample.df$sample,n=-1))
# [1] NA 1.2500000 1.2000000 1.1666667 1.1428571 0.5000000 0.5000000
# [8] 3.0000000 0.8333333 0.8000000 0.7500000 0.6666667 0.5000000 2.0000000
# [15] 1.5000000 1.3333333 1.2500000 1.2000000
请注意,您执行滚动应用的想法稍有问题,因为它会将数字除以前一个除法的结果,而不是之前的值。也就是说,一个滚动的鸿沟中的c(2,3,4)
应该以一个初始值(比如1
,即分区身份)开始,然后选择c(2/1, 3/(2/1), 4/(3/(2/1)))
,而不是(我认为)你要求了。
这使得该功能成为:
division <- function(x) c(NA, tail(x,n=-1) / head(x,n=-1))
那么你可以做到
lapply(sample.df, division)
如果您只想在选择列上运行此功能,请执行
ind <- 1
lapply(sample.df[ind], division)
# $sample
# [1] NA 1.2500000 1.2000000 1.1666667 1.1428571 0.5000000 0.5000000
# [8] 3.0000000 0.8333333 0.8000000 0.7500000 0.6666667 0.5000000 2.0000000
# [15] 1.5000000 1.3333333 1.2500000 1.2000000
cbind(sample.df, lapply(sample.df[ind], division))
# sample desired sample
# 1 4 1 NA
# 2 5 1 1.2500000
# 3 6 1 1.2000000
# 4 7 1 1.1666667
# 5 8 1 1.1428571
# 6 4 1 0.5000000
# 7 2 1 0.5000000
# 8 6 1 3.0000000
# 9 5 1 0.8333333
# 10 4 1 0.8000000
# 11 3 1 0.7500000
# 12 2 1 0.6666667
# 13 1 1 0.5000000
# 14 2 1 2.0000000
# 15 3 1 1.5000000
# 16 4 1 1.3333333
# 17 5 1 1.2500000
# 18 6 1 1.2000000
这当然会产生一个重复的名称,但这只是一个开始。
BTW:滚动通常与向量上的累积过程有关。您正在寻找的是单独为每个向量应用一个函数并捕获响应。
答案 1 :(得分:1)
以下是一些方法:
1)差异
transform(sample.df, desired = c(NA, exp(diff(log(sample)))))
## sample desired
## 1 4 NA
## 2 5 1.2500000
## 3 6 1.2000000
## 4 7 1.1666667
## 5 8 1.1428571
## ... etc ...
使用内置数据框anscombe
:
rbind(NA, exp(diff(log(as.matrix(anscombe)))))
2)diff.zoo
library(zoo)
z <- zoo(sample.df$sample)
merge(z, desired = diff(z, arith = FALSE), all = TRUE)
## z desired
## 1 4 NA
## 2 5 1.2500000
## 3 6 1.2000000
## 4 7 1.1666667
## 5 8 1.1428571
## ... etc ...
将其应用于anscombe
的所有列:
z <- zoo(rbind(NA, anscombe))
diff(z, arith = FALSE)
3)dplyr
library(dplyr)
sample.df %>% mutate(desired = sample/lag(sample))
## sample desired
## 1 4 NA
## 2 5 1.2500000
## 3 6 1.2000000
## 4 7 1.1666667
## 5 8 1.1428571
## ... etc ...
将其应用于anscombe
的所有列:
anscombe %>% mutate_all(funs(. / lag(.)))
4)rollapplyr
library(zoo)
transform(sample.df, desired = rollapplyr(sample, 2, function(x) x[2]/x[1], fill = NA))
## sample desired
## 1 4 NA
## 2 5 1.2500000
## 3 6 1.2000000
## 4 7 1.1666667
## 5 8 1.1428571
将其应用于anscombe
的所有列:
rollapplyr(anscombe, 2, function(x) x[2]/x[1], fill = NA))
5)lag.ts
transform(sample.df, desired = c(NA, lag(ts(sample)) / ts(sample)))
## sample desired
## 1 4 NA
## 2 5 1.2500000
## 3 6 1.2000000
## 4 7 1.1666667
## 5 8 1.1428571
要将其应用于anscombe
的所有列,请使用以下内容。请注意,不应该加载dplyr,因为它使用自己的lag
令人讨厌lag
。或者使用stats::lag
:
lag(ts(anscombe)) / ts(anscombe)