R data.table:如何将列中前面的每个0更改为1?
我有以下R data.table,它只由一列组成:R data.table:如何将列中前面的每个0更改为1?,r,dataframe,data.table,R,Dataframe,Data.table,我有以下R data.table,它只由一列组成: library(data.table) DT <- data.table(first_column = c(0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0)) > DT first_column 1: 0 2: 0 3: 0 4: 1 5:
library(data.table)
DT <- data.table(first_column = c(0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0))
> DT
first_column
1: 0
2: 0
3: 0
4: 1
5: 1
6: 1
7: 0
8: 0
9: 1
10: 1
11: 0
12: 0
13: 0
14: 0
15: 1
16: 1
17: 1
18: 1
19: 1
20: 0
21: 0
... ...
库(data.table)
DT
第一列
1: 0
2: 0
3: 0
4: 1
5: 1
6: 1
7: 0
8: 0
9: 1
10: 1
11: 0
12: 0
13: 0
14: 0
15: 1
16: 1
17: 1
18: 1
19: 1
20: 0
21: 0
... ...
二进制列第一列由连续列的“簇”组成
我想为每个集群将前面的每个0都转换为1。不知何故,我们会检查1
,然后将前面的0更改为1
编辑:为了更清楚,模式000110011000011111…
将变成0011110111100011111…
使用diff
尝试此操作:
DT$first_column[diff(DT$first_column)==1] <- 1
# first_column
# 1: 0
# 2: 0
# 3: 1
# 4: 1
# 5: 1
# 6: 1
# 7: 0
# 8: 1
# 9: 1
# 10: 1
# 11: 0
# 12: 0
# 13: 0
# 14: 1
# 15: 1
# 16: 1
# 17: 1
# 18: 1
# 19: 1
# 20: 0
# 21: 0
# first_column
DT$first\u column[diff(DT$first\u column)==1]使用diff尝试此操作:
DT$first_column[diff(DT$first_column)==1] <- 1
# first_column
# 1: 0
# 2: 0
# 3: 1
# 4: 1
# 5: 1
# 6: 1
# 7: 0
# 8: 1
# 9: 1
# 10: 1
# 11: 0
# 12: 0
# 13: 0
# 14: 1
# 15: 1
# 16: 1
# 17: 1
# 18: 1
# 19: 1
# 20: 0
# 21: 0
# first_column
DT$first\u column[diff(DT$first\u column)==1]这将用1替换每个0/1“组”的最终值,这对于1组来说是多余的,但您希望在0中完成什么(如果我正确阅读了您的问题)
rleid
用于将相邻的0和1分组,并且head
使用-1保留除最后一个元素以外的所有元素。或者更好的是,您可以使用@Frank建议的replace
,如下所示
DT[, replace(first_column, .N, 1), by=rleid(first_column)]
其中.N
用于指定组中的最后一行。这两种情况都会出现
rleid V1
1: 1 0
2: 1 0
3: 1 1
4: 2 1
5: 2 1
6: 2 1
7: 3 0
8: 3 1
9: 4 1
10: 4 1
11: 5 0
12: 5 0
13: 5 0
14: 5 1
15: 6 1
16: 6 1
17: 6 1
18: 6 1
19: 6 1
20: 7 0
21: 7 1
rleid V1
这些解决方案(错误地)用1填充最终观察结果。避免这种情况的一种方法是在填充值之前添加检查
DT[, if(.I[.N] < nrow(DT)) replace(first_column, .N, 1) else first_column,
by=rleid(first_column)]
DT[,if(.I[.N]
这里,.I[.N]
为每个组返回TRUE,但最后一组除外。此组的最终观察结果保留为“原样”。这将用1替换每个0/1“组”的最终值,这对于1组来说是多余的,但您希望在0时完成什么(如果我正确阅读了您的问题)
rleid
用于将相邻的0和1分组,并且head
使用-1保留除最后一个元素以外的所有元素。或者更好的是,您可以使用@Frank建议的replace
,如下所示
DT[, replace(first_column, .N, 1), by=rleid(first_column)]
其中.N
用于指定组中的最后一行。这两种情况都会出现
rleid V1
1: 1 0
2: 1 0
3: 1 1
4: 2 1
5: 2 1
6: 2 1
7: 3 0
8: 3 1
9: 4 1
10: 4 1
11: 5 0
12: 5 0
13: 5 0
14: 5 1
15: 6 1
16: 6 1
17: 6 1
18: 6 1
19: 6 1
20: 7 0
21: 7 1
rleid V1
这些解决方案(错误地)用1填充最终观察结果。避免这种情况的一种方法是在填充值之前添加检查
DT[, if(.I[.N] < nrow(DT)) replace(first_column, .N, 1) else first_column,
by=rleid(first_column)]
DT[,if(.I[.N]
这里,.I[.N]
为每个组返回TRUE,但最后一组除外。这个组的最后一个观察结果是“按原样”的。如果我正确理解OP,他希望将子序列0,1
的任何出现转换为1,1
:
DT <- data.table(first_column = c(0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0))
DT[first_column == 0 & shift(first_column, type = "lead") == 1, first_column := 1]
DT[, first_column]
# [1] 0 0 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 1 1 0 0
这里使用的事实是,0
被视为FALSE
,任何不等于0
的数字被视为TRUE
如果我正确理解OP,他希望将子序列0,1
的任何出现转换为1,1
:
DT <- data.table(first_column = c(0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0))
DT[first_column == 0 & shift(first_column, type = "lead") == 1, first_column := 1]
DT[, first_column]
# [1] 0 0 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 1 1 0 0
这里使用的事实是,0
被视为FALSE
,任何不等于0
的数字被视为TRUEDT[,v:=do.call(pmax,shift(first_column,0:1,type=“lead”,fill=0)]
,我猜。或者DT[DT[first_column==1,which=TRUE]-1L,first_column:=1]@Frank第二个对我来说很有意义。DT[,v:=do.call(pmax,shift(first_column,0:1,type=“lead”,fill=0))
,我猜。或者DT[first_column==1,which=TRUE]-1L,first_column:=1]
@Frank第二个对我来说很有意义。c(head(x,-,1),1)
是replace(x,.N,1)
,我想是吧。顺便说一句,最后一行的输出是错误的,哦,太好了。在此上下文中,我没有想到replace
。我猜您没有看到我的评论的编辑,但您的输出不正确。第21行应该还有零。c(头(x,-1),1)
是replace(x,.N,1)
,我猜。顺便说一句,最后一行的输出是错误的,哦,太好了。在此上下文中,我没有想到replace
。我猜您没有看到我的评论的编辑,但您的输出不正确。第21行仍应为零。