na.locf 仅当另一列未更改时
na.locf only if another column hasn't changed
我之前对 zoo::na.locf 创建了一些自定义调整,但这个让我抓狂。我需要一个函数,仅当 另一列中的值未更改时,该函数才会继续对列的最后一次观察 ;这一切都必须按主键分组。例如:
library(dplyr)
set.seed(20180409)
data <- data.frame(Id = rep(1:10, each = 24),
Date = rep(seq.Date(as.Date("2016-01-01"), as.Date("2017-12-01"),
by = "month"), 10),
FillCol = replace(runif(240), runif(240) < 0.9, NA),
CheckCol = rep(letters[1:7], each = 7, length.out = 240))
data <- data %>%
group_by(Id) %>%
mutate(CheckColHasChanged = replace(lag(CheckCol) != CheckCol,
is.na(lag(CheckCol) != CheckCol), TRUE),
FillColIsNA = is.na(FillCol))
因此,我试图将 FillCol 的任何观察结果向前推进,但是一旦我们遇到 CheckColHasChanged 的观察结果,就停止向前推进,直到 FillCol 中的下一个有效观察结果。我可以循环完成,但我正在努力正确地完成它。
Fill <- TRUE #indicator for whether or not I should be carrying forward
for(row in 2:nrow(data)){
#if the CheckCol has changed, don't fill
if(data$CheckColHasChanged[row]){Fill <- FALSE}
#if we should fill and still have the same Id, then fill from the last obs
if(Fill & data$Id[row] == data$Id[row - 1]){
data$FillCol[row] <- data$FillCol[row - 1]
}else{ #if there's a valid obs in FillCol, set the indicator back to true
if(!data$FillColIsNA[row]){Fill <- TRUE}
}
}
如有任何帮助,我们将不胜感激!
回答评论:这只是Id和CheckCol的填写:
data %>% group_by(Id, CheckCol) %>%
mutate(result = zoo::na.locf(FillCol, na.rm = FALSE))
按照您描述的方式 CheckCol
,它就像 ID 一样对待。 "only if the values in another column haven't changed"和"grouped by a primary key"没有区别。您只有两列可以分组。
我之前对 zoo::na.locf 创建了一些自定义调整,但这个让我抓狂。我需要一个函数,仅当 另一列中的值未更改时,该函数才会继续对列的最后一次观察 ;这一切都必须按主键分组。例如:
library(dplyr)
set.seed(20180409)
data <- data.frame(Id = rep(1:10, each = 24),
Date = rep(seq.Date(as.Date("2016-01-01"), as.Date("2017-12-01"),
by = "month"), 10),
FillCol = replace(runif(240), runif(240) < 0.9, NA),
CheckCol = rep(letters[1:7], each = 7, length.out = 240))
data <- data %>%
group_by(Id) %>%
mutate(CheckColHasChanged = replace(lag(CheckCol) != CheckCol,
is.na(lag(CheckCol) != CheckCol), TRUE),
FillColIsNA = is.na(FillCol))
因此,我试图将 FillCol 的任何观察结果向前推进,但是一旦我们遇到 CheckColHasChanged 的观察结果,就停止向前推进,直到 FillCol 中的下一个有效观察结果。我可以循环完成,但我正在努力正确地完成它。
Fill <- TRUE #indicator for whether or not I should be carrying forward
for(row in 2:nrow(data)){
#if the CheckCol has changed, don't fill
if(data$CheckColHasChanged[row]){Fill <- FALSE}
#if we should fill and still have the same Id, then fill from the last obs
if(Fill & data$Id[row] == data$Id[row - 1]){
data$FillCol[row] <- data$FillCol[row - 1]
}else{ #if there's a valid obs in FillCol, set the indicator back to true
if(!data$FillColIsNA[row]){Fill <- TRUE}
}
}
如有任何帮助,我们将不胜感激!
回答评论:这只是Id和CheckCol的填写:
data %>% group_by(Id, CheckCol) %>%
mutate(result = zoo::na.locf(FillCol, na.rm = FALSE))
按照您描述的方式 CheckCol
,它就像 ID 一样对待。 "only if the values in another column haven't changed"和"grouped by a primary key"没有区别。您只有两列可以分组。