用于创建连续计数列的for循环的替代方案

3

我有一个数据框,看起来像这样:

 x <- data.frame("Name" = c("Jorge", "Jorge", "Jorge", "Tom", "Tom", "Jerry", "Tom", "Tom", "Jorge"),
                 "Date" = c("10-13-2017", "10-12-2017", "10-11-2017", "10-10-2017", "10-09-2017", 
                            "10-08-2017", "10-07-2017", "10-06-2017", "10-05-2017"))

我想要创建一个统计姓名列中“连胜次数”的列。最终结果应该如下所示:

 Name       Date  Streak
 Jorge 10-13-2017      3
 Jorge 10-12-2017      2
 Jorge 10-11-2017      1
 Tom   10-10-2017      2
 Tom   10-09-2017      1
 Jerry 10-08-2017      1
 Tom   10-07-2017      2
 Tom   10-06-2017      1
 Jorge 10-05-2017      1

我目前拥有的是:

streak <- 1
for(i in NROW(x):2){

j <- i - 1

if(as.character(x[i, "Name"]) == as.character(x[j, "Name"])){
streak = streak + 1
x[i, "Streak"] = streak
}

else{
 x[i, "Streak"] = 1
 streak <- 1
}
}

这将得到:

 Name       Date  Streak
 Jorge 10-13-2017      3
 Jorge 10-12-2017      3
 Jorge 10-11-2017      2
 Tom   10-10-2017      1
 Tom   10-09-2017      2
 Jerry 10-08-2017      1
 Tom   10-07-2017      1
 Tom   10-06-2017      2
 Jorge 10-05-2017      1

这不太对,我很难想出如何得到预期的输出。理想情况下,我不需要使用for循环,因为这是一个包含数万行数据的大型数据集,所以速度非常慢。
所以我的问题是:
1. 有没有一种方法可以不使用for循环来实现? 2. 如何从底部开始计数,以便输出反映所需的连胜?
感谢任何帮助。
2个回答

4
您可以使用基本的 R 语言中的 rle 函数(运行长度编码)来实现此操作……
x$Streak <- unlist(sapply(rle(as.character(x$Name))$lengths, seq, 1, -1))

x
   Name       Date Streak
1 Jorge 10-13-2017      3
2 Jorge 10-12-2017      2
3 Jorge 10-11-2017      1
4   Tom 10-10-2017      2
5   Tom 10-09-2017      1
6 Jerry 10-08-2017      1
7   Tom 10-07-2017      2
8   Tom 10-06-2017      1
9 Jorge 10-05-2017      1

这将获取每个名称的运行长度,为它们生成一个递减的序列,然后(通过取消列表)将它们转换为向量。


1
我们可以使用data.table。将“data.frame”转换为“data.table”(setDT(x)),按“Name”的运行长度ID(rleid)分组,获取行数的数字序列的反向,并赋值(:=)以创建“Streak”列。
library(data.table)
setDT(x)[, Streak := rev(seq_len(.N)), rleid(Name)]
x
#    Name       Date Streak
#1: Jorge 10-13-2017      3
#2: Jorge 10-12-2017      2
#3: Jorge 10-11-2017      1
#4:   Tom 10-10-2017      2
#5:   Tom 10-09-2017      1
#6: Jerry 10-08-2017      1
#7:   Tom 10-07-2017      2
#8:   Tom 10-06-2017      1
#9: Jorge 10-05-2017      1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接