我有一个这样的数据集,
x time
1 TRUE 9
2 TRUE 8
3 TRUE 10
4 TRUE 5
5 TRUE 16
6 FALSE 2
7 FALSE 17
8 FALSE 6
9 TRUE 11
10 TRUE 7
11 TRUE 20
12 TRUE 3
13 TRUE 10
14 FALSE 4
15 FALSE 2
16 FALSE 10
17 TRUE 3
18 TRUE 6
使用r,我想生成一个新的变量,为基于x和时间的条件变化分配一个唯一的数字。具体来说,我想从头开始搜索数据,并为第一行分配一个数字(例如,1)。当x的条件在TRUE和False之间变化时,数量会增加。在"x是假的"条件下,该数字将保持不变。然而,在"x为真"中,条件,当"x为TRUE,时间"10",但当满足"x为TRUE且时间" = 10"的条件时,数字也会加1,并保持不变,直到满足下一次更改条件。
换句话说,TRUE和False之间的变化被认为是条件的变化。另外,当"x为true"时,每次当时间为"gt;10也被认为是一个新条件的开始。
我想要得到的输出是这样的。
x time count
1 TRUE 9 1
2 TRUE 8 1
3 TRUE 10 2
4 TRUE 5 2
5 TRUE 16 3
6 FALSE 2 4
7 FALSE 17 4
8 FALSE 6 4
9 TRUE 11 5
10 TRUE 7 5
11 TRUE 20 6
12 TRUE 3 6
13 TRUE 9 6
14 FALSE 4 7
15 FALSE 2 7
16 FALSE 10 7
17 TRUE 3 8
18 TRUE 6 8
19 TRUE 15 9
我尝试了id(x),但它肯定没有考虑时间变量的变化。我将感谢任何关于如何解决这个问题的建议!
这是rleid
的一个选项-在列'x'上使用rleid
,并基于'time'列创建数字索引
library(data.table)
setDT(df1)[, count := rleid(x, replace(x, x, cumsum(time[x] >= 10)))]
与产出
x time count
<lgcl> <int> <int>
1: TRUE 9 1
2: TRUE 8 1
3: TRUE 10 2
4: TRUE 5 2
5: TRUE 16 3
6: FALSE 2 4
7: FALSE 17 4
8: FALSE 6 4
9: TRUE 11 5
10: TRUE 7 5
11: TRUE 20 6
12: TRUE 3 6
13: TRUE 9 6
14: FALSE 4 7
15: FALSE 2 7
16: FALSE 10 7
17: TRUE 3 8
18: TRUE 6 8
19: TRUE 15 9
或与dplyr
library(dplyr)
df1 %>%
mutate(count = rleid(x, replace(x, x, cumsum(time[x] >= 10))))
与产出
x time count
1 TRUE 9 1
2 TRUE 8 1
3 TRUE 10 2
4 TRUE 5 2
5 TRUE 16 3
6 FALSE 2 4
7 FALSE 17 4
8 FALSE 6 4
9 TRUE 11 5
10 TRUE 7 5
11 TRUE 20 6
12 TRUE 3 6
13 TRUE 9 6
14 FALSE 4 7
15 FALSE 2 7
16 FALSE 10 7
17 TRUE 3 8
18 TRUE 6 8
19 TRUE 15 9
数据df1 <- structure(list(x = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE,
FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE,
TRUE, TRUE), time = c(9L, 8L, 10L, 5L, 16L, 2L, 17L, 6L, 11L,
7L, 20L, 3L, 9L, 4L, 2L, 10L, 3L, 6L, 15L)), row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19"), class = "data.frame")
可以在base r中使用for
循环
# Your data, copied from @akrun
df1 <- structure(list(x = c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE,
FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE,
TRUE, TRUE), time = c(9L, 8L, 10L, 5L, 16L, 2L, 17L, 6L, 11L,
7L, 20L, 3L, 9L, 4L, 2L, 10L, 3L, 6L, 15L)), row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19"), class = "data.frame")
# Create an empty `count` column
df1$count <- 0
# Assign 1 to the first row
df1$count[1] <- 1
# From the 2nd row up to the last row, increase the count number if
# one two #conditions is satisfied. Otherwise, the count number should
# remain unchanged.
for (k in 2:nrow(df1)) {
# The two conditions for increase of count number:
# (1)there is a change in x OR (2) x is TRUE and time >=10
if( df1$x[k] != df1$x[k-1] | (df1$x[k] == TRUE & df1$time[k] >= 10)){
df1$count[k] <- df1$count[k-1] + 1
}
else df1$count[k] <- df1$count[k-1]
}
df1
x time count
1 TRUE 9 1
2 TRUE 8 1
3 TRUE 10 2
4 TRUE 5 2
5 TRUE 16 3
6 FALSE 2 4
7 FALSE 17 4
8 FALSE 6 4
9 TRUE 11 5
10 TRUE 7 5
11 TRUE 20 6
12 TRUE 3 6
13 TRUE 9 6
14 FALSE 4 7
15 FALSE 2 7
16 FALSE 10 7
17 TRUE 3 8
18 TRUE 6 8
19 TRUE 15 9