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))))))