在同一数据帧中排列具有不同条件的时段

时间:2015-05-26 15:22:55

标签: r rank

我想根据某些条件对具有不同标准的数据帧的行进行排名。

我有一个包含以下数据的数据框:采样日期,采样日期月份,种群中繁殖个体的百分比和格里高利天数。

如果超过20%的人口正在繁殖期间(繁殖期),我想以不同的方式对行进行排名。 我有这个信息好几个月,但在这里我只写了两个:

    mydf <- read.table(text="sampling_date - month - breeder - gregorian_days
    1/1/00-1-0-1
    5/1/00-1-10-5
    9/1/00-1-50-9
    13/1/00-1-100-13
    17/1/00-1-30-17
    21/1/00-1-20-21
    25/1/00-1-12-25
    29/1/00-1-3-29
    1/2/00-2-10-33
    5/2/00-2-20-37
    9/2/00-2-50-41
    13/2/00-2-80-45
    17/2/00-2-50-49
    21/2/00-2-51-53
    25/2/00-2-30-57
    28/2/00-2-10-61"
    , sep="-", header=TRUE)
mydf

我想在每个月内排名行:

(1)在第一行之前,值小于20写A

(2)从第一个值高于20,开始排名,但每3个实日排名行(例如排名1 =第5,6,7天;排名2 =第8,9,10天...) 。因此,繁殖期内的所有行都不必是连续的。某些等级可能不会作为第一个月的4添加。

要执行此操作,直到最后一行的值大于20

(3)在最后一行之后,一个值大于20的B

下面我添加了我想要的结果

   sampling_date month breeder gregorian_days rank
1         1/1/00     1       0              1    A
2         5/1/00     1      10              5    A
3         9/1/00     1      50              9    1
4        13/1/00     1     100             13    2
5        17/1/00     1      30             17    3
6        21/1/00     1      20             21    5
7        25/1/00     1      12             25    B
8        29/1/00     1       3             29    B
9         1/2/00     2      10             33    A
10        5/2/00     2      20             37    1
11        9/2/00     2      50             41    2
12       13/2/00     2      80             45    3
13       17/2/00     2      50             49    5
14       21/2/00     2      51             53    6
15       25/2/00     2      30             57    7
16       28/2/00     2      10             61    B

开始排名的阈值可能是基于数据框的一列值的标准,或者我可以获得确切的日期来定义期间繁殖期内外的不同行为。

例如,阈值

    Start<- c("9/1/00", "5/2/00")
    End <- c("21/1/00", "25/2/00")

我所拥有的就是每个月制作一个循环,使用函数if将值更高和更低20更改但我不知道如何在繁殖期内进行排名。

你能帮帮我吗?

提前致谢

1 个答案:

答案 0 :(得分:2)

'...'

备注:

  • 我使用df <- data.frame(sampling_date=c('1/1/00','5/1/00','9/1/00','13/1/00','17/1/00', '21/1/00','25/1/00','29/1/00','1/2/00','5/2/00', '9/2/00','13/2/00','17/2/00','21/2/00','25/2/00','28/2/00'), month=c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2), breeder=c(0,10,50,100,30,20,12,3,10,20,50,80,50,51,30,10), gregorian_days=c(1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61)) df$sampling_date <- as.Date(df$sampling_date,'%d/%m/%y') df$rank <- do.call(c, by(df, df$month, function(x) { breeding <- x$breeder>=20 first <- which(breeding)[1] start <- x$sampling_date[first] ifelse(breeding, as.integer(x$sampling_date-start)%/%3+1, c('A','B')[(1:nrow(x)>=first)+1]) })) df ## sampling_date month breeder gregorian_days rank ## 1 2000-01-01 1 0 1 A ## 2 2000-01-05 1 10 5 A ## 3 2000-01-09 1 50 9 1 ## 4 2000-01-13 1 100 13 2 ## 5 2000-01-17 1 30 17 3 ## 6 2000-01-21 1 20 21 5 ## 7 2000-01-25 1 12 25 B ## 8 2000-01-29 1 3 29 B ## 9 2000-02-01 2 10 33 A ## 10 2000-02-05 2 20 37 1 ## 11 2000-02-09 2 50 41 2 ## 12 2000-02-13 2 80 45 3 ## 13 2000-02-17 2 50 49 5 ## 14 2000-02-21 2 51 53 6 ## 15 2000-02-25 2 30 57 7 ## 16 2000-02-28 2 10 61 B 将您的约会时间强制转移到Date班级以准备日期算术。
  • 我已将as.Date(...,'%d/%m/%y');函数用于分组逻辑。我选择by()而不是by()aggregate(),因为后两者一次只能处理一列,但逻辑需要多列(特别是ave()和{{1 } {},sampling_date支持。此外,breeder始终将聚合数据与输入data.frame按列组合,将每个组强制为单行,因此通常不适用于多元素返回值;为此需要by()aggregate()
  • 在我的解决方案中,我预先计算(1)一个逻辑向量,表示哪些行是“繁殖日”,哪些不是(ave()),(2)第一个繁殖日行索引(by() ),和(3)第一个繁殖日breeding值(first)。然后我用育种期Date分支。
  • 对于繁殖日,我每天减去日期减去开始日,并使用整数除以3(加1)得到等级值。
  • 对于非繁殖日,我根据非繁殖日是在start之前还是之后发生而对ifelse(breeding,...)进行索引。