我有以下数据帧dat,它在一些行的开头呈现行特定数量的NA:
dat <- as.data.frame(rbind(c(NA,NA,1,3,5,NA,NA,NA), c(NA,1:3,6:8,NA), c(1:7,NA)))
dat
# V1 V2 V3 V4 V5 V6 V7 V8
# NA NA 1 3 5 NA NA NA
# NA 1 2 3 6 7 8 NA
# 1 NA 2 3 4 5 6 NA
Run Code Online (Sandbox Code Playgroud)
我的目标是删除每行开头的所有NA,并左移行值(相应地在移位行的末尾添加NA,以保持其长度不变).
以下代码按预期工作:
for (i in 1:nrow(dat)) {
if (is.na(dat[i,1])==TRUE) {
dat1 <- dat[i, min(which(!is.na(dat[i,]))):length(dat[i,])]
dat[i,] <- data.frame( dat1, t(rep(NA, ncol(dat)-length(dat1))) )
}
}
dat
Run Code Online (Sandbox Code Playgroud)
返回:
# V1 V2 V3 V4 V5 V6 V7 V8
# 1 3 5 NA NA NA NA NA
# 1 2 3 6 7 8 NA NA
# 1 NA 2 3 4 5 6 NA
Run Code Online (Sandbox Code Playgroud)
我想知道在没有使用for循环和使用tail函数的情况下有更直接的方法.
关于最后一点,通过使用min(which(!is.na(dat[1,])))结果3,如预期的那样.但是如果我键入tail(dat[1,],min(which(!is.na(dat[1,]))))结果是相同的初始行,我不明白为什么..
非常感谢anu的建议.
如果你只想把所有的NA推到最后,你可以试试
dat <- as.data.frame(rbind(c(NA,NA,1,3,5,NA,NA,NA), c(NA,1:3,6:8,NA), c(1:7,NA)))
dat[3,2] <- NA
> dat
V1 V2 V3 V4 V5 V6 V7 V8
1 NA NA 1 3 5 NA NA NA
2 NA 1 2 3 6 7 8 NA
3 1 NA 3 4 5 6 7 NA
dat.new<-do.call(rbind,lapply(1:nrow(dat),function(x) t(matrix(dat[x,order(is.na(dat[x,]))])) ))
colnames(dat.new)<-colnames(dat)
> dat.new
V1 V2 V3 V4 V5 V6 V7 V8
[1,] 1 3 5 NA NA NA NA NA
[2,] 1 2 3 6 7 8 NA NA
[3,] 1 3 4 5 6 7 NA NA
Run Code Online (Sandbox Code Playgroud)
我认为你不能在没有循环的情况下做到这一点。
dat <- as.data.frame(rbind(c(NA,NA,1,3,5,NA,NA,NA), c(NA,1:3,6:8,NA), c(1:7,NA)))
dat[3,2] <- NA
# V1 V2 V3 V4 V5 V6 V7 V8
# 1 NA NA 1 3 5 NA NA NA
# 2 NA 1 2 3 6 7 8 NA
# 3 1 NA 3 4 5 6 7 NA
t(apply(dat, 1, function(x) {
if (is.na(x[1])) {
y <- x[-seq_len(which.min(is.na(x))-1)]
length(y) <- length(x)
y
} else x
}))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#[1,] 1 3 5 NA NA NA NA NA
#[2,] 1 2 3 6 7 8 NA NA
#[3,] 1 NA 3 4 5 6 7 NA
Run Code Online (Sandbox Code Playgroud)
如果需要的话,然后将矩阵转换为 data.frame 。