考虑:的R - 填补空变量
v1 <- c(1,NA,1,NA,NA)
v2 <- c(NA,NA,1,NA,1)
df <- data.frame(rbind(v1, v2))
R> df
X1 X2 X3 X4 X5
1 NA 1 NA NA
NA NA 1 NA 1
我如何填写1
之间的'NA'
?
,使它看起来像这样:
X1 X2 X3 X4 X5
1 1 1 NA NA
NA NA 1 1 1
考虑:的R - 填补空变量
v1 <- c(1,NA,1,NA,NA)
v2 <- c(NA,NA,1,NA,1)
df <- data.frame(rbind(v1, v2))
R> df
X1 X2 X3 X4 X5
1 NA 1 NA NA
NA NA 1 NA 1
我如何填写1
之间的'NA'
?
,使它看起来像这样:
X1 X2 X3 X4 X5
1 1 1 NA NA
NA NA 1 1 1
我不知道你的数据集有多大,但你可以采取更长的方法,并使用任何一种方法获得更高效的结果e以下:
选项1:使用arr.ind
。选项二:使用max.col
。
myFun2 <- function(indf) {
indf2 <- replace(indf, is.na(indf), 0)
mins <- max.col(indf2, "first")
maxs <- max.col(indf2, "last")
L <- Map(seq.int, mins, maxs)
mat <- cbind(rep(seq_along(L), lengths(L)), unlist(L, use.names = FALSE))
indf[mat] <- 1
indf
}
myFun2(df)
用一些不同大小的数据进行测试。这里有一个方法,使数据:
set.seed(1)
nc <- 50
nr <- 10000
df <- data.frame(t(replicate(nr, sample(c(1, 1, rep(NA, nc-2))))))
一些样本输出和时序比较见this Gist。
只想说选项2为我工作。谢谢! – kquach
我们可以通过该行与apply
与MARGIN=1
循环做到这一点。查找第一个和最后一个非NA元素的索引,并使用第一个非NA元素更改它们之间的元素,转置输出并将其分配回数据集。
df[] <- t(apply(df, 1, function(x) {
st <- range(which(!is.na(x)))
x[st[1]:st[2]] <- x[st[1]]
x}))
另一个apply
解决方案上MARGIN=2
用的lag
和lead
功能的使用从dplyr
:
library(dplyr)
v1 <- c(1,NA,1,NA,NA)
v2 <- c(NA,NA,1,NA,1)
dff <- data.frame(rbind(v1, v2))
apply(t(dff), 2, function(x) {
conds <- rowSums(cbind(x, lag(x), lead(x)), na.rm = T)==2
x[conds] <- 1
x
}) %>% t()
输出:
# X1 X2 X3 X4 X5
# v1 1 1 1 NA NA
# v2 NA NA 1 1 1
似乎适用于给定的例子,但不是一般的... – A5C1D2H2I1M1N2O1R2T1
如果有人对我之前的评论感到好奇,请查看https://gist.github.com/mrdwab/048f4323217bade1168a9b3dff521b22。 – A5C1D2H2I1M1N2O1R2T1
有多种方法可以做到这一点。你有什么尝试? –
每行只有2列值为1吗?有更多1s的可能性吗?更少1s?在这些情况下你想要什么行为? – A5C1D2H2I1M1N2O1R2T1
只要考虑最简单的情况,其中每行有2个1的值。它们可以相邻(可以保持不变),也可以在两者之间缺少值。谢谢! – kquach