在R中为相同的值添加一列索引

时间:2013-03-11 14:05:44

标签: r

我希望根据我每年发生的事件数据集制作一个图块。举个例子,我的数据是这样的:

set.seed(123)
data <- data.frame(years = sample(2000:2010, 50, replace = T))

我想将这些绘制为x =年的平铺图,但是在多次出现的年份中保持事件之间的分离(y方向)。问题是我没有其他专栏给我一个年份倍数的连续y值。

为了说明,我有这个:

data[data$years == 2002, ]
[1] 2002 2002 2002 2002

我认为我需要这样的事情:

data[data$years == 2002, ]
    years   index
1    2002       1
2    2002       2
3    2002       3
4    2002       4

然后我可以使用x = yearsy = index进行平铺。

感谢您的任何建议!

4 个答案:

答案 0 :(得分:5)

也许使用plyr

ddply(data, .(years), mutate, index=1:length(years))

给出了:

   years index
1   2000     1
2   2000     2
3   2000     3
4   2001     1
5   2001     2
6   2001     3
7   2001     4
8   2001     5
9   2002     1
10  2002     2
11  2002     3
12  2002     4
13  2002     5

答案 1 :(得分:3)

我首先按years对数据进行排序,然后使用ave,如下所示:

set.seed(123)
data <- data.frame(years = sample(2000:2010, 50, replace = T))
data <- data[order(data$years), , drop = F]
data$index <- ave(data$years, data$years, FUN=seq_along)

# a piece of output
#    years index
# 6   2000     1
# 18  2000     2
# 35  2000     3
# 15  2001     1
# 30  2001     2
# 41  2001     3
# 45  2001     4
# 46  2001     5
# 17  2002     1
# 38  2002     2
# 40  2002     3
# 47  2002     4
# 49  2002     5

修改:您也可以不使用ave进行排序,只需跳过排序为的第一行:

set.seed(123)
data <- data.frame(years = sample(2000:2010, 50, replace = T))
data$index <- ave(data$years, data$years, FUN=seq_along)
> head(data)

#   years index
# 1  2003     1
# 2  2008     1
# 3  2004     1
# 4  2009     1
# 5  2010     1
# 6  2000     1

请注意,现在订单已保留。现在,如果我们为2002进行了子集:

data[data$years == 2002, ]

#    years index
# 17  2002     1
# 38  2002     2
# 40  2002     3
# 47  2002     4
# 49  2002     5

答案 2 :(得分:2)

可能不是最优雅的..只是添加另一种方式。

set.seed(123)
data <- data.frame(years = sample(2000:2010, 50, replace = T))
cbind(data[order(data), ], unlist(sapply(rle(data[order(data), ])$lengths, FUN = seq)))
##       [,1] [,2]
##  [1,] 2000    1
##  [2,] 2000    2
##  [3,] 2000    3
##  [4,] 2001    1
##  [5,] 2001    2
##  [6,] 2001    3
##  [7,] 2001    4
##  [8,] 2001    5
##  [9,] 2002    1
## [10,] 2002    2
## [11,] 2002    3
## [12,] 2002    4
## [13,] 2002    5
## [14,] 2003    1
## [15,] 2003    2
## [16,] 2003    3
## [17,] 2003    4
## [18,] 2004    1
## [19,] 2004    2
## [20,] 2004    3
## [21,] 2004    4
## [22,] 2004    5
## [23,] 2005    1
## [24,] 2005    2
## [25,] 2005    3
## [26,] 2005    4
## [27,] 2005    5
## [28,] 2006    1
## [29,] 2006    2
## [30,] 2006    3
## [31,] 2007    1
## [32,] 2007    2
## [33,] 2007    3
## [34,] 2007    4
## [35,] 2007    5
## [36,] 2007    6
## [37,] 2008    1
## [38,] 2008    2
## [39,] 2008    3
## [40,] 2009    1
## [41,] 2009    2
## [42,] 2009    3
## [43,] 2009    4
## [44,] 2009    5
## [45,] 2009    6
## [46,] 2010    1
## [47,] 2010    2
## [48,] 2010    3
## [49,] 2010    4
## [50,] 2010    5

**根据Arun的建议,下面的内容更为简单。

cbind(data[order(data), ],sequence(rle(data[order(data), ])$lengths))

答案 3 :(得分:1)

本着分享的精神,这是另一种在基地R中做到这一点的方式:

stack(with(data, by(years, years, FUN = seq_along)))

以下是前几行:

> head(stack(with(data, by(years, years, FUN = seq_along))), 10)
   values  ind
1       1 2000
2       2 2000
3       3 2000
4       1 2001
5       2 2001
6       3 2001
7       4 2001
8       5 2001
9       1 2002
10      2 2002

就此而言,任何split-apply-combine方法都可能是合适的,例如:

stack(sapply(split(data$years, data), seq_along))
stack(tapply(data$years, data$years, FUN = seq_along))

然而,来自@Arun的ave解决方案和来自@juba的“plyr”解决方案更适合将列添加到多列数据集而不是这些,只是因为它们的灵活性。