我有一个数据框,缺少"SNAP_ID"的值.我想基于前一个非缺失值(lag()?)的序列用浮点值填充缺失值.如果可能的话,我真的想用dplyr实现这个目的.
假设:
目前的数据:
end SNAP_ID
1 2015-06-26 12:59:00 365
2 2015-06-26 13:59:00 366
3 2015-06-27 00:01:00 NA
4 2015-06-27 23:00:00 NA
5 2015-06-28 00:01:00 NA
6 2015-06-28 23:00:00 NA
7 2015-06-29 09:00:00 367
8 2015-06-29 09:59:00 368
Run Code Online (Sandbox Code Playgroud)
我想要实现的目标:
end SNAP_ID
1 2015-06-26 12:59:00 365.0
2 2015-06-26 13:59:00 366.0
3 2015-06-27 00:01:00 366.1
4 2015-06-27 23:00:00 366.2
5 2015-06-28 00:01:00 366.3
6 2015-06-28 23:00:00 366.4
7 2015-06-29 09:00:00 367.0
8 2015-06-29 09:59:00 368.0
Run Code Online (Sandbox Code Playgroud)
作为数据框架:
df <- structure(list(end = structure(c(1435323540, 1435327140, 1435363260,
1435446000, 1435449660, 1435532400, 1435568400, 1435571940), tzone = "UTC", class = c("POSIXct",
"POSIXt")), SNAP_ID = c(365, 366, NA, NA, NA, NA, 367, 368)), .Names = c("end",
"SNAP_ID"), row.names = c(NA, -8L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)
这是我尝试实现这一目标,但它只适用于第一个缺失值:
df %>%
arrange(end) %>%
mutate(SNAP_ID=ifelse(is.na(SNAP_ID),lag(SNAP_ID)+0.1,SNAP_ID))
end SNAP_ID
1 2015-06-26 12:59:00 365.0
2 2015-06-26 13:59:00 366.0
3 2015-06-27 00:01:00 366.1
4 2015-06-27 23:00:00 NA
5 2015-06-28 00:01:00 NA
6 2015-06-28 23:00:00 NA
7 2015-06-29 09:00:00 367.0
8 2015-06-29 09:59:00 368.0
Run Code Online (Sandbox Code Playgroud)
来自@ mathematical.coffee的优秀答案如下:
df %>%
arrange(end) %>%
group_by(tmp=cumsum(!is.na(SNAP_ID))) %>%
mutate(SNAP_ID=SNAP_ID[1] + 0.1*(0:(length(SNAP_ID)-1))) %>%
ungroup() %>%
select(-tmp)
Run Code Online (Sandbox Code Playgroud)
编辑:新版本适用于任意数量的NA运行.这个也不需要zoo.
首先,请注意tmp=cumsum(!is.na(SNAP_ID))组SNAP_IDS,从而相同的基团tmp由一个非NA值,后跟NA值的游程的.
然后按此变量分组,只需将.1添加到第一个SNAP_ID以填写NA:
df %>%
arrange(end) %>%
group_by(tmp=cumsum(!is.na(SNAP_ID))) %>%
mutate(SNAP_ID=SNAP_ID[1] + 0.1*(0:(length(SNAP_ID)-1)))
end SNAP_ID tmp
1 2015-06-26 12:59:00 365.0 1
2 2015-06-26 13:59:00 366.0 2
3 2015-06-27 00:01:00 366.1 2
4 2015-06-27 23:00:00 366.2 2
5 2015-06-28 00:01:00 366.3 2
6 2015-06-28 23:00:00 366.4 2
7 2015-06-29 09:00:00 367.0 3
8 2015-06-29 09:59:00 368.0 4
Run Code Online (Sandbox Code Playgroud)
然后您可以在tmp之后删除该列(添加%>% select(-tmp)到结尾).
编辑:这是旧版本,不适用于后续运行的NAs.
如果你的目标是用前一个值+ 0.1填充每个NA,你可以使用zoo's na.locf(NA用前一个值填充每个),同时cumsum(is.na(SNAP_ID))*0.1添加额外的0.1.
library(zoo)
df %>%
arrange(end) %>%
mutate(SNAP_ID=ifelse(is.na(SNAP_ID),
na.locf(SNAP_ID) + cumsum(is.na(SNAP_ID))*0.1,
SNAP_ID))
Run Code Online (Sandbox Code Playgroud)