我有一个数据集,可以对几个病人进行连续温度测量。数据集是不完整的,包含许多NA值。然而,患者可能在实验结束前死亡,因此从死亡时间到测量期结束时记录了NA。我想要做的是按行(个别病人)进行我的数据帧,最后进行观察,除非没有记录进一步的观察结果。一个小的示例数据框将是:
df<-data.frame(H0=c(35.4, 36.0, 36.0, 36.4), H1=c(NA, 34.0, 33.4, NA),
H2=c(NA, 33.5, NA, 34.2), H3=c(32.9, NA, 34.0, NA),
H4=c(NA, 33.1, NA, NA), H5=c(33.2, NA, NA, 32.8))
我有点与动物园合作并申请:
df2<-apply(df, 1, na.locf)
虽然这会创建一个矩阵而不是数据框架,并且为死亡的病人带来温度,直到实验结束,这不是我想要做的。患者2&amp; 3如果两者仍然以H5结束,那么。
答案 0 :(得分:2)
转置,使用na.fill
用0填充trailinig NA并使用na.locf
填写剩余的NA并转置回来。最后用NAs替换零:
library(zoo)
df0 <- t(na.locf(na.fill(t(df), c(NA, NA, 0))))
ifelse(df0 == 0, NA, df0)
,并提供:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 35.4 35.4 35.4 32.9 32.9 33.2
[2,] 36.0 34.0 33.5 33.5 33.1 NA
[3,] 36.0 33.4 33.4 34.0 NA NA
[4,] 36.4 36.4 34.2 34.2 34.2 32.8
也可以这样写:
zero2NA <- function(x) ifelse(x == 0, NA, x)
t(apply(df, 1, function(x) zero2NA( na.locf( na.fill(x, c(NA, NA, 0))))))
答案 1 :(得分:1)
如果查看?na.locf
,您会看到有一个选项na.rm可以保留领先的 NAs。因此,通过反转两次,您可以预先设置尾随的NA。问题是,在这种情况下,它使用端点而不是它正在替换的间隔的第一个点,并且使用fromLast和na.rm并不解决这个问题(不保留NA)。因此,一个丑陋但有效的解决方案是首先保留NA(但用错误的值替换),然后用正确的值替换(不预先确定NA),最后通过重新插入应该在那里的NA来纠正...它&# 39; s不漂亮,但它有效
res1 <- t(apply(df, 1, function(y) rev(na.locf(rev(y), na.rm = F))))
res2 <- t(apply(df, 1, na.locf))
res2[is.na(res1)] <- NA
res2
# H0 H1 H2 H3 H4 H5
#[1,] 35.4 35.4 35.4 32.9 32.9 33.2
#[2,] 36.0 34.0 33.5 33.5 33.1 NA
#[3,] 36.0 33.4 33.4 34.0 NA NA
#[4,] 36.4 36.4 34.2 34.2 34.2 32.8
编辑 @ G.Grothendieck提出的更紧凑和优雅的方法
tdf.na <- na.locf(t(df), fromLast = TRUE)
t(ifelse(is.na(tdf.na), NA, na.locf(t(df))))
# H0 H1 H2 H3 H4 H5
#[1,] 35.4 35.4 35.4 32.9 32.9 33.2
#[2,] 36.0 34.0 33.5 33.5 33.1 NA
#[3,] 36.0 33.4 33.4 34.0 NA NA
#[4,] 36.4 36.4 34.2 34.2 34.2 32.8
答案 2 :(得分:1)
这是一个基本解决方案:
t(apply(df, 1, function(a) {
i <- is.na(a)
ifelse(rev(cummin(rev(i)) != 1), a[which(!i)[cumsum(!i)]], NA)
}))
## H0 H1 H2 H3 H4 H5
## [1,] 35.4 35.4 35.4 32.9 32.9 33.2
## [2,] 36.0 34.0 33.5 33.5 33.1 NA
## [3,] 36.0 33.4 33.4 34.0 NA NA
## [4,] 36.4 36.4 34.2 34.2 34.2 32.8