Tar*_*rak 27 r missing-data zoo dplyr
我有一个数据框,按日期的降序排列.
ps1 = data.frame(userID = c(21,21,21,22,22,22,23,23,23),
color = c(NA,'blue','red','blue',NA,NA,'red',NA,'gold'),
age = c('3yrs','2yrs',NA,NA,'3yrs',NA,NA,'4yrs',NA),
gender = c('F',NA,'M',NA,NA,'F','F',NA,'F')
)
Run Code Online (Sandbox Code Playgroud)
我希望将NA值用先前的值归入(替换)并按userID分组如果userID的第一行有NA,则替换为该用户ID组的下一组值.
我正在尝试使用像这样的dplyr和zoo软件包......但它不起作用
cleanedFUG <- filteredUserGroup %>%
group_by(UserID) %>%
mutate(Age1 = na.locf(Age),
Color1 = na.locf(Color),
Gender1 = na.locf(Gender) )
Run Code Online (Sandbox Code Playgroud)
我需要结果df像这样:
userID color age gender
1 21 blue 3yrs F
2 21 blue 2yrs F
3 21 red 2yrs M
4 22 blue 3yrs F
5 22 blue 3yrs F
6 22 blue 3yrs F
7 23 red 4yrs F
8 23 red 4yrs F
9 23 gold 4yrs F
Run Code Online (Sandbox Code Playgroud)
Ren*_*rop 42
require(tidyverse) #fill is part of tidyr
ps1 %>%
group_by(userID) %>%
fill(color, age, gender) %>% #default direction down
fill(color, age, gender, .direction = "up")
Run Code Online (Sandbox Code Playgroud)
哪个给你:
Source: local data frame [9 x 4]
Groups: userID [3]
userID color age gender
<dbl> <fctr> <fctr> <fctr>
1 21 blue 3yrs F
2 21 blue 2yrs F
3 21 red 2yrs M
4 22 blue 3yrs F
5 22 blue 3yrs F
6 22 blue 3yrs F
7 23 red 4yrs F
8 23 red 4yrs F
9 23 gold 4yrs F
Run Code Online (Sandbox Code Playgroud)
直接在整个 data.frame 上使用zoo::na.locf将填充 NA,无论userID组如何。不幸的是,dplyr 包的分组对功能没有影响na.locf,这就是我进行拆分的原因:
library(dplyr); library(zoo)
ps1 %>% split(ps1$userID) %>%
lapply(function(x) {na.locf(na.locf(x), fromLast=T)}) %>%
do.call(rbind, .)
#### userID color age gender
#### 21.1 21 blue 3yrs F
#### 21.2 21 blue 2yrs F
#### 21.3 21 red 2yrs M
#### 22.4 22 blue 3yrs F
#### 22.5 22 blue 3yrs F
#### 22.6 22 blue 3yrs F
#### 23.7 23 red 4yrs F
#### 23.8 23 red 4yrs F
#### 23.9 23 gold 4yrs F
Run Code Online (Sandbox Code Playgroud)
它的作用是首先将数据分成 3 个 data.frames,然后我应用第一遍插补(向下),然后使用 中的匿名函数向上lapply,最后用于rbind将 data.frames 重新组合在一起。你有预期的输出。
小智 5
我写了这个函数,它肯定比 fill 更快,而且可能比 na.locf 更快:
fill_NA <- function(x) {
which.na <- c(which(!is.na(x)), length(x) + 1)
values <- na.omit(x)
if (which.na[1] != 1) {
which.na <- c(1, which.na)
values <- c(values[1], values)
}
diffs <- diff(which.na)
return(rep(values, times = diffs))
}
Run Code Online (Sandbox Code Playgroud)