创建一个新的变量,用于计算R中重复的长度

时间:2016-06-17 20:01:06

标签: r count duplicates aggregate

我有一个数据框,我想创建一个变量z,计算“y变量”的副本,如果y有1,1 set z = 2,2,如果y有3,3,3,则设置z = 3,3,3。

 x = c("a","b","c","d","e","a","b","c","d","e","a","b","c")
 y = c(1,1,2,2,2,3,3,4,4,4,5,5,5)
 data <- data.frame(x,y)
 data
    x y z
 1  a 1 2
 2  b 1 2
 3  c 2 3
 4  d 2 3
 5  e 2 3
 6  a 3 2
 7  b 3 2
 8  c 4 3
 9  d 4 3
 10 e 4 3
 11 a 5 3
 12 b 5 3
 13 c 5 3

感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

您可以尝试rle

data$z <- with(data, unlist(mapply(rep, rle(y)$lengths, rle(y)$lengths)))
data
   x y z
1  a 1 2
2  b 1 2
3  c 2 3
4  d 2 3
5  e 2 3
6  a 3 2
7  b 3 2
8  c 4 3
9  d 4 3
10 e 4 3
11 a 5 3
12 b 5 3
13 c 5 3

答案 1 :(得分:2)

如果您的变量y按照您所说的那样按递增顺序排序,那么以下解决方案将起作用:

# calculate counts of each level
counts <- table(data$y)
# fill in z
data$z <- counts[match(data$y, names(counts))]

但请注意,如果没有订购y,此方法将失败,因为您希望在发生不同级别时重新启动计数。出于这些目的,@ psidom的解决方案对于错误排序的数据更加健壮,因为rle将重置计数。

此方法计算某个级别的总出现次数,然后使用match将这些总计数提供到正确的位置。

答案 2 :(得分:1)

这是一个使用dplyr的快速方法,它的语法非常直观:

library(dplyr)

left_join(data, data %>%
                group_by(y) %>%
                summarize(z = n()), 
          by = "y")

   x y z
1  a 1 2
2  b 1 2
3  c 2 3
4  d 2 3
5  e 2 3
6  a 3 2
7  b 3 2
8  c 4 3
9  d 4 3
10 e 4 3
11 a 5 3
12 b 5 3
13 c 5 3

答案 3 :(得分:1)

我们可以使用data.table

轻松完成此操作
library(data.table)
setDT(data)[, z := .N , rleid(y)]
data
#    x y z
# 1: a 1 2
# 2: b 1 2
# 3: c 2 3
# 4: d 2 3
# 5: e 2 3
# 6: a 3 2
# 7: b 3 2
# 8: c 4 3
# 9: d 4 3
#10: e 4 3
#11: a 5 3
#12: b 5 3
#13: c 5 3

或使用rle中的base R而不使用任何loops

inverse.rle(within.list(rle(data$y), values <- lengths))
#[1] 2 2 3 3 3 2 2 3 3 3 3 3 3

使用ave

的其他基本R方法
with(data, ave(y, cumsum(c(TRUE, y[-1]!= y[-length(y)])), FUN=length))
#[1] 2 2 3 3 3 2 2 3 3 3 3 3 3