r - 有条件地逐列替换领先和落后的 NA
问题描述
我努力根据第一个和最后一个非缺失值的不同条件以不同方式填写 NA。
背景:人们接受白内障手术并改变晶状体phak
状态pseudo
。如果第一个非缺失值是“phak”,则这必须存在于以前未记录的观察中。如果最后一个非缺失值是“伪”,则可以继续进行,因为状态不能变回“phak”。
不能简单地使用这样的函数,zoo::na.locf
因为如果在 switch 之间存在 NA,我们将无法确定操作的确切时间,并且这些值应该保持 NA。因此,这不是一个“三明治”问题
library(tidyverse)
a <- c(NA, 'phak', NA, 'pseudo', NA)
b <- c(NA, 'pseudo', NA, NA, NA)
c <- c('phak', 'phak', NA, NA, NA)
dfoo <- data.frame(a,b,c, stringsAsFactors = FALSE) %>% gather(eye, status)
dfoo
#> eye status
#> 1 a <NA>
#> 2 a phak
#> 3 a <NA>
#> 4 a pseudo
#> 5 a <NA>
#> 6 b <NA>
#> 7 b pseudo
#> 8 b <NA>
#> 9 b <NA>
#> 10 b <NA>
#> 11 c phak
#> 12 c phak
#> 13 c <NA>
#> 14 c <NA>
#> 15 c <NA>
所需的数据框:
#> eye status
#> 1 a phak
#> 2 a phak
#> 3 a <NA>
#> 4 a pseudo
#> 5 a pseudo
#> 6 b <NA>
#> 7 b pseudo
#> 8 b pseudo
#> 9 b pseudo
#> 10 b pseudo
#> 11 c phak
#> 12 c phak
#> 13 c <NA>
#> 14 c <NA>
#> 15 c <NA>
以下适用于简单的 vector,但我很难在数据帧中按组使用此解决方案。
# by vector:
# first conditionally replace leading NAs
if(a[min(which(!is.na(a)))] == 'phak') {a[1 : min(which(!is.na(a)))] <- 'phak'}
# next conditionally replace last NAs
if(a[max(which(!is.na(a)))] == 'pseudo') {a[max(which(!is.na(a))): length(a)] <- 'pseudo'}
a
#> [1] "phak" "phak" NA "pseudo" "pseudo"
由reprex 包(v0.3.0)于 2019 年 12 月 16 日创建
解决方案
这是一种可能的 tidyverse 方法:
group_by
视线水平- 创建两个临时列
phak
,pseudo
分别替换所有"pseudo"
值和"phak"
值NA
fill
使用的phak
列.direction = "up"
fill
使用的pseudo
列.direction = "down"
coalesce
phak
和列在pseudo
列中重新组合在一起status
library(tidyverse)
dfoo %>%
group_by(eye) %>%
mutate(
phak = na_if(status, "pseudo"),
pseudo = na_if(status, "phak")
) %>%
fill(phak, .direction = "up") %>%
fill(pseudo, .direction = "down") %>%
transmute(status = coalesce(phak, pseudo)) %>%
ungroup()
#> # A tibble: 15 x 2
#> eye status
#> <chr> <chr>
#> 1 a phak
#> 2 a phak
#> 3 a <NA>
#> 4 a pseudo
#> 5 a pseudo
#> 6 b <NA>
#> 7 b pseudo
#> 8 b pseudo
#> 9 b pseudo
#> 10 b pseudo
#> 11 c phak
#> 12 c phak
#> 13 c <NA>
#> 14 c <NA>
#> 15 c <NA>
数据
dfoo <- structure(list(eye = c("a", "a", "a", "a", "a", "b", "b", "b",
"b", "b", "c", "c", "c", "c", "c"), status = c(NA, "phak", NA,
"pseudo", NA, NA, "pseudo", NA, NA, NA, "phak", "phak", NA, NA,
NA)), row.names = c(NA, -15L), class = "data.frame")
推荐阅读
- deep-learning - 强化学习:为什么重新开始训练后学习的准确率会下降?
- angular - 我可以为 Angular 6 中模块的所有子路由加载一个组件吗?
- kubernetes - Ingress 无法解析 GKE 中的 NodePort IP
- apache - URL重写apache
- c# - 如何从 CSV 文件中构建 C# 字典,其中键位于一列,值位于另一列?
- reactjs - 渲染一个字符串数组的状态。推后,得到我 [object Object]
- typescript - express-jwt 和 express-graphql:错误 TS2339:“请求”类型上不存在属性“用户”
- visual-studio-code - 如何启用参考搜索视图扩展
- javascript - 如何列出道具变量中的项目?
- javascript - RangeError:时间值无效