我有一个R数据框:
a <- 1:12
list <- c(rep("x",3),rep("y",4),rep("z",3),rep("x",2))
data <- data.frame(a,list)
data
a list
1 x
2 x
3 x
4 y
5 y
6 y
7 y
8 z
9 z
10 z
11 x
12 x
我想创建一个新列,每当“list”的值发生变化时,该列开始计数为1,即在此示例中:
b <- c(1:3,1:4,1:3,1:2)
data <- data.frame(a,list,b)
我远不是R的专家,也不能为我的生活找到一种有效的方法。我的主要问题似乎是 “list”的任何值都可以随时返回,但是对于一个值的块的长度没有规则。 有没有人有任何想法? 谢谢!
答案 0 :(得分:6)
我会使用rle()
获取list
的运行长度,然后使用方便的sequence()
函数从{{返回的$lengths
组件生成所需的计数器1}}:
rle()
请注意,我们必须将R> sequence(rle(as.character(data$list))$lengths)
[1] 1 2 3 1 2 3 4 1 2 3 1 2
转换为原子向量(在我的情况下为字符向量),因为list
中不允许使用该因子。
将其放入rle()
,然后将其包含在
data
给出了
data <- transform(data, b = sequence(rle(as.character(list))$lengths))
答案 1 :(得分:5)
关键的想法是在rle()
上使用data$list
(运行长度编码)(在将其强制转换为原子向量之后 - 毕竟,我们对特定条目不感兴趣)。然后我们使用seq()
创建从1开始并以计算的运行长度结束的序列。最后,我们将所有这些序列粘贴在一起:
unlist(lapply(rle(as.numeric(data$list))$lengths,FUN=seq,from=1))