假设我们需要对大于 40 的连续数字进行计数,但按分组(标签)进行计数,以便连续数字的计数应独立于标签。
例如,我们有来自标签列的 6 个组,因此对于每个组,我们将计算临时变量超过阈值的次数。下面是我试图与此一起呈现的可重现示例,我粘贴了预期输出的快照。
tag<- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6)
temp<- c(43, 44, 45, 41, 43, 38, 40, 41, 39, 37, 37, 39, 45, 42, 41, 43, 44, 39,38,
37, 43, 44, 45, 41, 43, 38, 40, 41, 39, 37, 37, 39, 45, 42, 41, 43, 44,
39, 38, 37, 43, 44, 45, 41, 43, 38, 40, 41, 39, 37, 37, 39, 45, 42, 41,43,
44, 39, 38, 37)
df=data.frame(tag=tag,temp=temp)
预期输出是第三列状态
最佳答案
我们可以使用data.table
。将“data.frame”转换为“data.table”(setDT(df)
),使用逻辑向量的游程 ID 创建分组变量 (temp >= 40
),按“tag”、“grp”分组并设置逻辑条件i
,我们将“status”指定为行序列(seq_len(.N)
),并将 'status' 中的 'NA' 元素转换为 0
library(data.table)
setDT(df)[, grp := rleid(temp >= 40)][temp >= 40, status := seq_len(.N) , .(tag, grp)
][is.na(status), status := 0][]
head(df, 20)
# tag temp grp status
# 1: 1 43 1 1
# 2: 1 44 1 2
# 3: 1 45 1 3
# 4: 1 41 1 4
# 5: 1 43 1 5
# 6: 1 38 2 0
# 7: 1 40 3 1
# 8: 1 41 3 2
# 9: 1 39 4 0
#10: 1 37 4 0
#11: 2 37 4 0
#12: 2 39 4 0
#13: 2 45 5 1
#14: 2 42 5 2
#15: 2 41 5 3
#16: 2 43 5 4
#17: 2 44 5 5
#18: 2 39 6 0
#19: 2 38 6 0
#20: 2 37 6 0
或者使用base R
中的rle
。我们使用ave
按'tag'分组,获取逻辑向量(temp >=40
)的rle
,复制值
乘以长度
,并将其与长度
的序列
相乘。 TRUE/FALSE
值被强制转换为 1/0
,当一个数字与 1 相乘时,它会返回该数字,而与 0 相乘时,我们会得到 0 值。
df$status <- with(df, ave(temp >= 40, tag, FUN = function(x) {
rl <- rle(x)
with(rl, sequence(lengths) * rep(values, lengths))}))
df$status
#[1] 1 2 3 4 5 0 1 2 0 0 0 0 1 2 3 4 5 0 0 0 1 2 3 4 5
#[26] 0 1 2 0 0 0 0 1 2 3 4 5 0 0 0 1 2 3 4 5 0 1 2 0 0 0 0 1 2 3 4 5 0 0 0
关于r - 计算给定数据框中连续不大于阈值但分组的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42219410/