【问题标题】:R compare current row to the next row (on same column)R将当前行与下一行(在同一列)进行比较
【发布时间】:2016-10-21 19:51:41
【问题描述】:

我有类似的东西:

ISBN   Date  Quantity
3457   2004  10
3457   2004  6
3457   2004  10
3457   2005  7
3457   2005  12
9885   2013  10
9885   2013  6
9855   2013  10
9885   2014  7
9885   2014  12

我想得到:

ISBN   Date  Quantity Year
3457   2004  10       1st Year
3457   2004  6        1st Year
3457   2004  10       1st Year
3457   2005  7        2nd Year
3457   2005  12       2nd Year
9885   2013  10       1st Year
9885   2013  6        1st Year
9855   2013  10       1st Year
9885   2014  7        2nd Year
9885   2014  12       2nd Year

我有这个代码:

df<-df %>% group_by(ISBN) %>% mutate(Year = ifelse(DateYear > DateYear,"1st Year","2nd Year"))

但我到处都只得到“第二年”,所以我猜ifelse 中的比较实际上并没有比较“日期”列中的行。我想我必须使用 for 循环,但我认为这是 R 中的其他方式。我怎样才能得到我需要的结果?

【问题讨论】:

标签: r


【解决方案1】:

根据 cmets 中提到的,如果您有更多案例,您可以这样做:

library(dplyr)
library(toOrdinal)

df %>%
  group_by(ISBN) %>%
  mutate(Year = paste(sapply(cumsum(Date != lag(Date, default = 0)), toOrdinal), "Year"))

例如:

#   ISBN Date Quantity
#1  3457 2004       10
#2  3457 2004        6
#3  3457 2005       10
#4  3457 2006        7
#5  3457 2007       12
#6  9885 2013       10
#7  9885 2014        6
#8  9855 2015       10
#9  9885 2015        7
#10 9885 2016       12

给予:

#Source: local data frame [10 x 4]
#Groups: ISBN [3]
#
#    ISBN  Date Quantity     Year
#   <int> <int>    <int>    <chr>
#1   3457  2004       10 1st Year
#2   3457  2004        6 1st Year
#3   3457  2005       10 2nd Year
#4   3457  2006        7 3rd Year
#5   3457  2007       12 4th Year
#6   9885  2013       10 1st Year
#7   9885  2014        6 2nd Year
#8   9855  2015       10 1st Year
#9   9885  2015        7 3rd Year
#10  9885  2016       12 4th Year

【讨论】:

    【解决方案2】:

    使用windowing logic

    library(dplyr)
    library(readr)
    
    df_foo = read.table(textConnection("ISBN   Date  Quantity
    3457   2004  10
    3457   2004  6
    3457   2004  10
    3457   2005  7
    3457   2005  12
    9885   2013  10
    9885   2013  6
    9855   2013  10
    9885   2014  7
    9885   2014  12"), header = TRUE, stringsAsFactors = FALSE)
    
    
    df_foo %>% 
      group_by(ISBN) %>% 
      arrange(Date) %>% 
      mutate(
        ifelse(
        cumsum(Date != lag(Date, default = first(Date))),
        "2nd Year", "1st Year"
        )
      )
    

    【讨论】:

    • 它很接近,但它给出了:
    • 对不起。它很接近但它给出了:ISBN Date Quantity Year 3457 2004 10 1st Year 3457 2004 6 1st Year 3457 2004 10 1st Year 3457 2005 7 2nd Year 3457 2005 12 1st Year 9885 2013 10 1st Year 9885 2013 6 1st Year 9855 2013 10 1st Year 9885 2014 7 2nd Year 9885 2014 12 1st Year 所以在它第一次给出正确的结果 2004>2003="2nd Year" 之后,它会持续到 2004>2004="1st Year"
    • @adlisval 你确定每个 ISBN 中只有两年吗?
    • @adlisval 已更新。
    • 感谢@tchakravarty,它成功了。看来我没有足够的积分 (15) 来投票,抱歉。
    【解决方案3】:

    只是为了完整性,因为我个人更喜欢这样的解决方案,这里是一个只使用基础 R 的解决方案,依靠 splitlapply 来实现结果。实际上,它会遍历 ISBN 的不同值。

    # examples data (note possible error on line 8, ISBN==9855)
    dat0 <- read.table(text="ISBN   Date  Quantity
    3457   2004  10
    3457   2004  6
    3457   2004  10
    3457   2005  7
    3457   2005  12
    9885   2013  10
    9885   2013  6
    9855   2013  10
    9885   2014  7
    9885   2014  12", header=T)
    
    # treat separately (loop using 'lapply')
    datlist <- split(dat,dat$ISBN)
    datlist <- lapply(datlist,
      function(x) within(x, Year <- as.numeric(as.factor(Date))))
    
    # bind together
    dat <- do.call(rbind, datlist)
    rownames(dat) <- NULL
    

    输出:

    #    ISBN Date Quantity Year
    # 1  3457 2004       10    1
    # 2  3457 2004        6    1
    # 3  3457 2004       10    1
    # 4  3457 2005        7    2
    # 5  3457 2005       12    2
    # 6  9855 2013       10    1
    # 7  9885 2013       10    1
    # 8  9885 2013        6    1
    # 9  9885 2014        7    2
    # 10 9885 2014       12    2
    

    请注意,此方法会重新排列数据集,以使行根据 ISBN 进行排序。此外,我没有费心用1st Year, 2nd Year, ... 等对Year 列进行编码,因为除了1, 2, ... 这样更简单的格式之外,我并没有真正看到其他价值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 2014-10-30
      • 2022-06-15
      • 2023-02-06
      • 1970-01-01
      相关资源
      最近更新 更多