我有一个标准的'可以避免循环'问题,但无法找到解决方案。
我回答this question by @splaisan,但我不得不在中间部分采用一些丑陋的扭曲,进行for
和多次if
测试。我在这里模拟一个更简单的版本,希望有人能给出更好的答案......
问题
给出这样的数据结构:
df <- read.table(text = 'type
a
a
a
b
b
c
c
c
c
d
e', header = TRUE)
我想识别相同类型的连续块并将它们分组。第一个块应标记为0,下一个块应标记为0,依此类推。有一个无限数量的块,每个块可能只有一个成员。
type label
a 0
a 0
a 0
b 1
b 1
c 2
c 2
c 2
c 2
d 3
e 4
我的解决方案
我不得不使用for
循环来执行此操作,这是代码:
label <- 0
df$label <- label
# LOOP through the label column and increment the label
# whenever a new type is found
for (i in 2:length(df$type)) {
if (df$type[i-1] != df$type[i]) { label <- label + 1 }
df$label[i] <- label
}
我的问题
任何人都可以在没有循环和条件的情况下执行此操作吗?
答案 0 :(得分:6)
使用rle
r <- rle(as.numeric(df$type))
df$label <- rep(seq(from=0, length=length(r$lengths)), times=r$lengths)
不使用rle
,而是使用cumsum
而不是强制转换为数字的逻辑。
df$label <- c(0,cumsum(df$type[-1] != df$type[-length(df$type)]))
两者都给:
> df
type label
1 a 0
2 a 0
3 a 0
4 b 1
5 b 1
6 c 2
7 c 2
8 c 2
9 c 2
10 d 3
11 e 4
答案 1 :(得分:3)
我对它的抨击:
as.numeric(df[, 1])-1
答案 2 :(得分:2)
这也刚好发生在我身上,你可以简单地转换为一个因子,然后回到整数并减去一个:
as.integer(as.factor(df$type))-1
如果type
已经是一个因素,您可以跳过该步骤。