Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R as SAS中的保留和滞后功能_R_Data.table - Fatal编程技术网

R as SAS中的保留和滞后功能

R as SAS中的保留和滞后功能,r,data.table,R,Data.table,我正在寻找一个类似于SAS中的lag1、lag2和retain函数的函数,我可以在data.tables中使用这些函数 我知道R中有像embed和lag这样的函数,但它们不返回单个值或以前的值。它们返回一组完整的向量 R中是否有我可以用于data.table的内容 有关SAS功能的更多信息: 您必须知道,R的工作原理与SAS中的数据步骤非常不同。SAS中的lag函数用于数据步骤,并在该数据步骤的隐式循环结构中使用。retain函数也是如此,它只是在通过数据循环时保持值不变 另一方面,R完全

我正在寻找一个类似于SAS中的
lag1
lag2
retain
函数的函数,我可以在data.tables中使用这些函数

我知道R中有像
embed
lag
这样的函数,但它们不返回单个值或以前的值。它们返回一组完整的向量

R中是否有我可以用于data.table的内容

有关SAS功能的更多信息:


您必须知道,R的工作原理与SAS中的数据步骤非常不同。SAS中的
lag
函数用于数据步骤,并在该数据步骤的隐式循环结构中使用。
retain
函数也是如此,它只是在通过数据循环时保持值不变

另一方面,R完全矢量化。这意味着你必须重新思考你想做什么,并相应地适应

  • retain
    在R中毫无用处,因为R默认情况下会回收参数。如果您想显式地执行此操作,可以查看eg
    rep()
    ,以构造具有常量值和特定长度的向量
  • lag
    是一个使用索引的问题,只是移动向量中所有值的位置。为了保持向量的长度相同,需要添加一些
    NA
    并删除一些额外的值
一个简单的示例:此SAS代码滞后于变量
x
,并添加具有常量值的变量
year

data one;
   retain year 2013;
   input x @@;
   y=lag1(x);
   z=lag2(x);
   datalines;
1 2 3 4 5 6
;
在R中,您可以编写自己的滞后函数,如下所示:

mylag <- function(x,k) c(rep(NA,k),head(x,-k))
结果是:

> one
  x  y  z year
1 1 NA NA 2013
2 2  1 NA 2013
3 3  2  1 2013
4 4  3  2 2013
5 5  4  3 2013
6 6  5  4 2013

对于
data.table
对象,情况也完全相同。这里重要的一点是重新思考您的策略:在使用R时,您必须开始考虑向量和索引,而不是像SAS中的数据步骤那样进行循环思考。

我想说,壁橱相当于
retain
lag1
,而
lag2
将是最重要的

它很容易与
数据表一起使用。例如:

library(data.table)
library(quantmod)
d <- data.table(v1=c(rep('a', 10), rep('b', 10)), v2=1:20)
setkeyv(d, 'v1')
d[,new_var := Lag(v2, 1), by='v1']
d[,new_var2 := v2-Lag(v2, 3), by='v1']
d[,new_var3 := Next(v2, 2), by='v1']
正如你所见,让你回顾过去,让你展望未来。这两个函数都很好,因为它们用NAs填充结果,使其与输入具有相同的长度

如果您想获得更高级、更高的性能,可以研究使用
data.table
对象的滚动联接。这与你所要求的有点不同,但在概念上是相关的,所以我必须与你分享

从data.table开始:

library(data.table)
library(quantmod)
set.seed(42)
d1 <- data.table(
    id=c(rep('a', 10), rep('b', 10)), 
    time=rep(1:10,2), 
    value=runif(20))
setkeyv(d1, c('id', 'time'))
print(d1)

    id time     value
 1:  a    1 0.9148060
 2:  a    2 0.9370754
 3:  a    3 0.2861395
 4:  a    4 0.8304476
 5:  a    5 0.6417455
 6:  a    6 0.5190959
 7:  a    7 0.7365883
 8:  a    8 0.1346666
 9:  a    9 0.6569923
10:  a   10 0.7050648
11:  b    1 0.4577418
12:  b    2 0.7191123
13:  b    3 0.9346722
14:  b    4 0.2554288
15:  b    5 0.4622928
16:  b    6 0.9400145
17:  b    7 0.9782264
18:  b    8 0.1174874
19:  b    9 0.4749971
20:  b   10 0.5603327
但是,data.table允许您在主索引内向前滚动次索引

d2[d1,,roll=TRUE]
    id time      value2     value
 1:  a    1          NA 0.9148060
 2:  a    2          NA 0.9370754
 3:  a    3          NA 0.2861395
 4:  a    4 0.811055141 0.8304476
 5:  a    5 0.811055141 0.6417455
 6:  a    6 0.811055141 0.5190959
 7:  a    7 0.811055141 0.7365883
 8:  a    8 0.811055141 0.1346666
 9:  a    9 0.811055141 0.6569923
10:  a   10 0.003948339 0.7050648
11:  b    1          NA 0.4577418
12:  b    2          NA 0.7191123
13:  b    3          NA 0.9346722
14:  b    4          NA 0.2554288
15:  b    5          NA 0.4622928
16:  b    6 0.737595618 0.9400145
17:  b    7 0.737595618 0.9782264
18:  b    8 0.388108283 0.1174874
19:  b    9 0.685169729 0.4749971
20:  b   10 0.685169729 0.5603327
这真是太酷了:旧的观察结果会随着时间向前滚动,直到被新的观察结果取代。如果要在序列开始时替换
NA
值,可以通过向后滚动第一个观察值来完成:

d2[d1,,roll=TRUE, rollends=c(TRUE, TRUE)]
    id time      value2     value
 1:  a    1 0.811055141 0.9148060
 2:  a    2 0.811055141 0.9370754
 3:  a    3 0.811055141 0.2861395
 4:  a    4 0.811055141 0.8304476
 5:  a    5 0.811055141 0.6417455
 6:  a    6 0.811055141 0.5190959
 7:  a    7 0.811055141 0.7365883
 8:  a    8 0.811055141 0.1346666
 9:  a    9 0.811055141 0.6569923
10:  a   10 0.003948339 0.7050648
11:  b    1 0.737595618 0.4577418
12:  b    2 0.737595618 0.7191123
13:  b    3 0.737595618 0.9346722
14:  b    4 0.737595618 0.2554288
15:  b    5 0.737595618 0.4622928
16:  b    6 0.737595618 0.9400145
17:  b    7 0.737595618 0.9782264
18:  b    8 0.388108283 0.1174874
19:  b    9 0.685169729 0.4749971
20:  b   10 0.685169729 0.5603327

这些滚动连接绝对令人难以置信,我从未见过它们在任何其他开源软件包中实现(有关更多信息,请参见
?data.table
)。关闭“SAS大脑”和打开“R大脑”需要一段时间,但一旦你克服了最初的困难,你会发现这种语言更具表现力。

要保留,请尝试以下方法:

retain<-function(x,event,outside=NA)
{
  indices <- c(1,which(event==TRUE), nrow(df)+1)
  values <- c(outside,x[event==TRUE])
  y<- rep(values, diff(indices)) 
}

retain以下是一个示例:使用sqldf累积值:

> w_cum <-
 sqldf("select t1.id, t1.SomeNumt, SUM(t2.SomeNumt) as cum_sum
       from w_cum       t1
       inner join w_cum t2 on t1.id >= t2.id
       group by t1.id, t1.SomeNumt
       order by t1.id
  • 1111
  • 21223
  • 3 13 36
  • 41450
  • 51565
  • 61681
  • 71798
  • 818116
  • 919135
  • 1020155


多年前,我们大多数R用户要么从未使用过SAS,要么烧掉了SAS手册来保暖。这些函数在SAS中做什么?Joris,我不想卷入编辑大战,但我做这些编辑是有原因的。这不是SAS问题,因此不需要标签;这个问题可以而且应该很容易地独立成一个关于R如何工作的问题,而不必提及SAS,除了提到lag函数,它可以帮助那些懂两种语言的人(以及对未来对lag有同样想法的用户的指南)。回答此问题的人不需要阅读SAS文档来回答此问题。@Joe OP的问题与他的SAS经验以及SAS和R之间的差异直接相关。只有当您知道SAS中的数据步骤是如何工作的,以及这与R方法有何不同时,他的问题才有意义。主要的问题是他的问题在R语境中没有意义;SAS中的
LAG
函数返回的R-like中没有“先前记录”这样的内容。因此,我(直截了当地)反对你的编辑。对不起,如果我粗鲁无礼,那不是我的本意。我的社交能力没有那么强。幸运的是我的电脑可以处理;-)我非常同情来到R的SAS用户,他正试图复制保留。在我使用R的最初几个小时里,我搜索并找到了一个
lag
函数,在尝试使用搞砸了的R时间序列对象时,我完全偏离了方向。NewRbies应该学习使用“zoo”软件包。@Joe SAS标签的使用是完全合理的,以便最大限度地查看可能独立使用R和SAS标签的人。查看SAS问题的人也可能具有回答此问题的R知识。我认为我们不需要为了一个标签就变得那么迂腐!
d2[d1,,roll=TRUE]
    id time      value2     value
 1:  a    1          NA 0.9148060
 2:  a    2          NA 0.9370754
 3:  a    3          NA 0.2861395
 4:  a    4 0.811055141 0.8304476
 5:  a    5 0.811055141 0.6417455
 6:  a    6 0.811055141 0.5190959
 7:  a    7 0.811055141 0.7365883
 8:  a    8 0.811055141 0.1346666
 9:  a    9 0.811055141 0.6569923
10:  a   10 0.003948339 0.7050648
11:  b    1          NA 0.4577418
12:  b    2          NA 0.7191123
13:  b    3          NA 0.9346722
14:  b    4          NA 0.2554288
15:  b    5          NA 0.4622928
16:  b    6 0.737595618 0.9400145
17:  b    7 0.737595618 0.9782264
18:  b    8 0.388108283 0.1174874
19:  b    9 0.685169729 0.4749971
20:  b   10 0.685169729 0.5603327
d2[d1,,roll=TRUE, rollends=c(TRUE, TRUE)]
    id time      value2     value
 1:  a    1 0.811055141 0.9148060
 2:  a    2 0.811055141 0.9370754
 3:  a    3 0.811055141 0.2861395
 4:  a    4 0.811055141 0.8304476
 5:  a    5 0.811055141 0.6417455
 6:  a    6 0.811055141 0.5190959
 7:  a    7 0.811055141 0.7365883
 8:  a    8 0.811055141 0.1346666
 9:  a    9 0.811055141 0.6569923
10:  a   10 0.003948339 0.7050648
11:  b    1 0.737595618 0.4577418
12:  b    2 0.737595618 0.7191123
13:  b    3 0.737595618 0.9346722
14:  b    4 0.737595618 0.2554288
15:  b    5 0.737595618 0.4622928
16:  b    6 0.737595618 0.9400145
17:  b    7 0.737595618 0.9782264
18:  b    8 0.388108283 0.1174874
19:  b    9 0.685169729 0.4749971
20:  b   10 0.685169729 0.5603327
retain<-function(x,event,outside=NA)
{
  indices <- c(1,which(event==TRUE), nrow(df)+1)
  values <- c(outside,x[event==TRUE])
  y<- rep(values, diff(indices)) 
}
df <- data.frame(w = c("a","b","c","a","b","c"), x = 1:6, y = c(1,1,2,2,2,3), stringsAsFactors = FALSE)
df$z<-retain(df$x-df$y,df$w=="b")
df
obtain<-function(x,event,outside=NA)
{
  indices <- c(0,which(event==TRUE), nrow(df))
  values <- c(x[event==TRUE],outside)
  y<- rep(values, diff(indices)) 
}
df$z2<-obtain(df$x-df$y,df$w=="b")
df
> w_cum <-
 sqldf("select t1.id, t1.SomeNumt, SUM(t2.SomeNumt) as cum_sum
       from w_cum       t1
       inner join w_cum t2 on t1.id >= t2.id
       group by t1.id, t1.SomeNumt
       order by t1.id
   id SomeNumt cum_sum