R data.table:如何将每个前面的0更改为列中的1?

时间:2017-04-25 16:02:15

标签: 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:            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
...          ...

二进制列first_column由连续列的“簇”组成。

我想为每个群集转动每个前面的0并将其转换为1.不知何故,一个检查1,然后将前面的0更改为1.

编辑:为了更清楚,模式0001110011000011111...将变为0011110111000111111...

3 个答案:

答案 0 :(得分:2)

使用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

基本上diff只会在1前面1输出0

答案 1 :(得分:2)

这将取代每个0/1&#34;组的最终值&#34;使用1,这对于1组来说是多余的,但是你想要为0做什么(如果我正确地读了你的问题)。

DT[, c(head(first_column, -1), 1), by=rleid(first_column)]

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

此处,.I[.N] < nrow(DT)为除最终组之外的每个组返回TRUE。这个小组的最终观察结果是&#34;原样。&#34;

答案 2 :(得分:2)

如果我正确理解了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

doublelogical的隐式类型转换为代价,可以更简洁地写成:

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 & shift(first_column, type = "lead"), 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