如何用 R 中大数据框中的另一个序列替换特定的数字序列(每行)?

How to replace a specific sequence of numbers (per row) with another sequence in a big data frame in R?

我有一个 data.frame,其中包含一组动物的 absence/presence 数据 (0/1),列为年份,行为个体。

我的数据:

df <- data.frame(Year1 = c('1','0','0','0','0','0'),
                 Year2 = c('1','1','1','0','0','0'),
                 Year3 = c('1','1','1','1','1','0'),
                 Year4 = c('0','1','0','0','0','1'),
                 Year5 = c('0','0','1','1','0','1'),
                 Year6 = c('0','0','0','1','1','1'))

df
     Year1 Year2 Year3 Year4 Year5 Year6
1:     1     1     1     0     0     0
2:     0     1     1     1     0     0
3:     0     1     1     0     1     0
4:     0     0     1     0     1     1
5:     0     0     1     0     0     1
6:     0     0     0     1     1     1

一些人有视力障碍(一年 (1) 见过,第二年 (0) 没见过,但第三年 (1) 再次发现)。总共有 400 行(=个人)。

我想做的是用1填充空白(1之间的0),这样上面的数据框就变成了:

df
     Year1 Year2 Year3 Year4 Year5 Year6
1:     1     1     1     0     0     0
2:     0     1     1     1     0     0
3:     0     1     1     1     1     0
4:     0     0     1     1     1     1
5:     0     0     1     1     1     1
6:     0     0     0     1     1     1

第一个 1 之前和最后一个 1 之后的零不应受到影响。

我浏览了很多 Whosebug 问题,例如:

find and replace numeric sequence in r

但是,我找不到同时适用于所有列、逐行处理的解决方案。

提前感谢您的建议! :)

我们可以按行进行。一个有效的选择是使用 collapse 中的 dapply。遍历行,找到 1s 的位置索引,得到第一个和最后一个之间的序列,并且 replace 那些元素为 1.

library(collapse)
dapply(df, MARGIN = 1, FUN = function(x)
     replace(x,  do.call(`:`, as.list(range(which(x == 1)))),  1 ))

-输出

  Year1 Year2 Year3 Year4 Year5 Year6
1     1     1     1     0     0     0
2     0     1     1     1     0     0
3     0     1     1     1     1     0
4     0     0     1     1     1     1
5     0     0     1     1     1     1
6     0     0     0     1     1     1

一个选项也是用whicharr.ind = TRUE获取row/column索引,然后创建序列,并使用row/column索引进行赋值已矢量化

ind <- which(df ==1, arr.ind = TRUE)
m1 <- as.matrix(transform(stack(lapply(split(ind[,2], ind[,1]), 
   function(x) x[1]:x[length(x)]))[2:1], ind = as.integer(ind)))
df[m1] <- 1

使用max.col在每一行中找到“第一个”和“最后一个”1,然后与col()umn个数进行比较:

df[col(df) >= max.col(df, "first") & col(df) <= max.col(df, "last")] <- 1
df

#  Year1 Year2 Year3 Year4 Year5 Year6
#1     1     1     1     0     0     0
#2     0     1     1     1     0     0
#3     0     1     1     1     1     0
#4     0     0     1     1     1     1
#5     0     0     1     1     1     1
#6     0     0     0     1     1     1

使用 apply -

的基础 R 方法
df[] <- t(apply(df, 1, function(x) {
  rg <- range(which(x == 1))
  x[rg[1]:rg[2]] <- 1
  x
}))

df

#  Year1 Year2 Year3 Year4 Year5 Year6
#1     1     1     1     0     0     0
#2     0     1     1     1     0     0
#3     0     1     1     1     1     0
#4     0     0     1     1     1     1
#5     0     0     1     1     1     1
#6     0     0     0     1     1     1