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

not*_*cta 5 replace r sequence gaps-in-data data.table

我有一个 data.frame,其中包含一组动物的缺席/存在数据 (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

Run Code Online (Sandbox Code Playgroud)

有些人有视力差距(一年看到(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

Run Code Online (Sandbox Code Playgroud)

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

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

在 r 中查找并替换数字序列

根据前面的值按组替换一系列值

但是,我找不到一种可以同时在所有列上逐行工作的解决方案。

预先感谢您的建议!:)

the*_*ail 7

用于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
Run Code Online (Sandbox Code Playgroud)


akr*_*run 3

我们可以按行执行此操作。一个有效的选择是使用dapplyfrom collapse。循环遍历行,找到1的位置索引,获取第一个和最后一个之间的序列,并将replace这些元素设置为1。

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

-输出

  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
Run Code Online (Sandbox Code Playgroud)

还可以选择使用which和获取行/列索引arr.ind = TRUE,然后创建序列,并使用行/列索引进行向量化的分配

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
Run Code Online (Sandbox Code Playgroud)