R-填充空变量
鉴于:R-填充空变量,r,dataframe,R,Dataframe,鉴于: 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 我们可以通过使用apply和MARGIN=1循环行来实现这一点。找到第一个和最后一个非NA元素的索引,并使用第一个非NA元素更改中间的元素,转换输出并将其分配回数据集 df[] <
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
我们可以通过使用
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}))
df[]使用dplyr
中的lag
和lead
功能,在MARGIN=2
上应用另一个解决方案:
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()
我不知道您的数据集有多大,但您可能可以采取更长的方法,并使用以下方法之一获得更有效的结果:
选项1:使用arr.ind
library(data.table)
myFun1 <- function(indf) {
M <- as.matrix(data.table(which(indf == 1, arr.ind = TRUE))[
, list(col = seq.int(min(col), max(col))), row])
indf[M] <- 1
indf
}
myFun1(df)
用不同大小的数据进行测试。以下是一种制作数据的方法:
set.seed(1)
nc <- 50
nr <- 10000
df <- data.frame(t(replicate(nr, sample(c(1, 1, rep(NA, nc-2))))))
set.seed(1)
nc有多种方法可以做到这一点。您尝试过什么?每行是否只有2列的值为1?是否有可能获得更多的1?更少的1?在这些情况下,你想要什么样的行为?只需考虑最简单的情况,其中每行有2个值为1s。它们可以是相邻的(可以保持不变),也可以是中间缺少值的。谢谢如果有人对我之前的评论感到好奇,请查看。
library(data.table)
myFun1 <- function(indf) {
M <- as.matrix(data.table(which(indf == 1, arr.ind = TRUE))[
, list(col = seq.int(min(col), max(col))), row])
indf[M] <- 1
indf
}
myFun1(df)
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))))))