[英]dplyr lag of different group
我試圖使用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))
非常感謝你!
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
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
}))
另一個與@ 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]]
這假定A和B是唯一的組。 如果有更多......
DT[, volag := DT[!.BY, on=.(group)][.(.SD$x - 1), on=.(x), roll=TRUE, x.value], by=group]
這個怎么運作:
:=
創建一個新列
DT[, col := ..., by=]
按每個by=
group分別進行每個賦值,基本上作為循環。
.BY
。 .SD
。 x[!i, on=]
是一個反連接,在x
查找i
行並返回x
並刪除匹配的行。
x[i, on=, roll=TRUE, xv]
......
on=
條件在x
查找i
每一行 on=
匹配時,它“滾動”到最后的on=
列的最接近的先前值 x
表返回v
有關更多詳細信息和直覺,請查看鍵入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)
試試這個:(僅管道方法)
library(zoo)
df %>%
mutate(groupLag = lag(group),
dupLag = group == groupLag) %>%
group_by(dupLag) %>%
mutate(valueLagHelp = lag(value)) %>%
ungroup() %>%
mutate(helper = ifelse(dupLag == T, NA, valueLagHelp)) %>%
mutate(helper = case_when(is.na(helper) ~ na.locf(helper, na.rm=F),
TRUE ~ helper)) %>%
mutate(valAfterLag = lag(dupLag)) %>%
mutate(otherLag = ifelse(is.na(lag(valueLagHelp)), lag(value), helper)) %>%
mutate(otherLag = ifelse((valAfterLag | is.na(valAfterLag)) & !dupLag,
lag(value), otherLag)) %>%
select(c(x, group, value, ownLag, otherLag))
對不起這個爛攤子。 它的作用是它首先創建一個組滯后並為該組等於其滯后的情況創建一個輔助變量(即當兩個“A”后續時。然后它按此輔助變量分組並分配給所有值為dupLag == F正確的值。現在我們需要用dupLag == T來處理那些值。
所以,取消組合。 我們需要一個新的滯后值助手,它將所有dupLag == T分配給NA,因為它們尚未正確分配。
接下來是我們在助手中為所有NA分配最后一個非NA值。 這不是全部,因為我們仍然需要處理一些dupLag == F數據點(當你查看完整的tibble時你會得到它)。 首先,我們基本上只用第一個mutate改變第二個數據點(otherLag == ...操作。下一個操作完成所有操作然后我們選擇我們最終想要擁有的變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.