我试图使用dplyr来改变包含变量的相同组滞后的列以及其他组(一个)的滞后.编辑:对不起,在第一版中,我通过在最后一秒按日期重新排列来搞砸了订单.
这就是我想要的结果:
library(tidyverse)
set.seed(2)
df <-
data.frame(
x = sample(seq(as.Date('2000/01/01'), as.Date('2015/01/01'), by="day"), 10),
group = sample(c("A","B"),10,replace = T),
value = sample(1:10,size=10)
) %>% arrange(x)
df <- df %>%
group_by(group) %>%
mutate(own_lag = lag(value))
df %>% data.frame(other_lag = c(NA,1,2,7,7,9,10,10,8,6))
Run Code Online (Sandbox Code Playgroud)
非常感谢你!
data.table的解决方案:
library(data.table)
# to create own lag:
setDT(df)[, own_lag:=c(NA, head(value, -1)), by=group]
# to create other group lag: (the function works actually outside of data.table, in base R, see N.B. below)
df[, other_lag:=sapply(1:.N,
function(ind) {
gp_cur <- group[ind]
if(any(group[1:ind]!=gp_cur)) tail(value[1:ind][group[1:ind]!=gp_cur], 1) else NA
})]
df
# x group value own_lag other_lag
#1: 2001-12-08 B 1 NA NA
#2: 2002-07-09 A 2 NA 1
#3: 2002-10-10 B 7 1 2
#4: 2007-01-04 A 5 2 7
#5: 2008-03-27 A 9 5 7
#6: 2008-08-06 B 10 7 9
#7: 2010-07-15 A 4 9 10
#8: 2012-06-27 A 8 4 10
#9: 2014-02-21 B 6 10 8
#10: 2014-02-24 A 3 8 6
Run Code Online (Sandbox Code Playgroud)
other_lag确定的解释:对于每个观察,想法是查看组值,如果存在与当前组不同的任何组值,则在当前组之前,然后取最后一个值,否则,放置NA.
注意: other_lag可以在不需要data.table的情况下创建:
df$other_lag <- with(df, sapply(1:nrow(df),
function(ind) {
gp_cur <- group[ind]
if(any(group[1:ind]!=gp_cur)) tail(value[1:ind][group[1:ind]!=gp_cur], 1) else NA
}))
Run Code Online (Sandbox Code Playgroud)
另一个与@ Cath's类似的数据表:
library(data.table)
DT = data.table(df)
DT[, vlag := shift(value), by=group]
DT[, volag := .SD[.(chartr("AB", "BA", group), x - 1), on=.(group, x), roll=TRUE, x.value]]
Run Code Online (Sandbox Code Playgroud)
这假定A和B是唯一的组.如果有更多......
DT[, volag := DT[!.BY, on=.(group)][.(.SD$x - 1), on=.(x), roll=TRUE, x.value], by=group]
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
:= 创建一个新列
DT[, col := ..., by=]每个by=组分别执行每个分配,基本上作为循环.
.BY..SD.x[!i, on=]是一种反连接,查找的行i中x并返回x与匹配的行删除.
x[i, on=, roll=TRUE, x.v] ...
i中x使用的on=条件on=找到完全匹配,则"滚动"到最后一on=列的最接近的先前值v从x表中返回有关更多详细信息和直觉,请查看键入时显示的启动消息library(data.table).
我不完全确定我是否正确地回答了你的问题,但如果“自己”和“其他”指的是 A 组和 B 组,那么这可能会起作用。我强烈认为有更优雅的方法可以做到这一点:
df.x <- df %>%
dplyr::group_by(group) %>%
mutate(value.lag=lag(value)) %>%
mutate(index=seq_along(group)) %>%
arrange(group)
df.a <- df.x %>%
filter(group=="A") %>%
rename(value.lag.a=value.lag)
df.b <- df.x %>%
filter(group=="B") %>%
rename(value.lag.b = value.lag)
df.a.b <- left_join(df.a, df.b[,c("index", "value.lag.b")], by=c("index"))
df.b.a <- left_join(df.b, df.a[,c("index", "value.lag.a")], by=c("index"))
df.x <- bind_rows(df.a.b, df.b.a)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |