【问题标题】:R compare column across rowsR跨行比较列
【发布时间】:2015-10-15 10:51:58
【问题描述】:

由于我或多或少是 R 的初学者,因此我遇到了以下问题。

我有一个类似的data.frame:

   a  b      c
1  x g1  date1
2  x g1  date2
3  y g2  date3
4  y g3  date4
5  y g4  date5
6  z g1  date6
7  z g2  date7
8  x g4  date8
9  y g1  date9
10 y g3 date10

我想做的是将a 列中的第一个值与第二个值进行比较。如果它们相同,则在 b 列中检查 g2 是否跟随 g1

数据按日期排序,我基本上想找到g2跟在g1之后的出现次数,而a列中的对应值相似。

在上面的示例数据中,总和为 1。(第 6 行和第 7 行)

【问题讨论】:

    标签: r compare


    【解决方案1】:

    可能有更简单的方法,但这是我的data.table 尝试

    library(data.table) ## v 1.9.6+
    setDT(df)[a == shift(a, type = "lead") & b == "g1" & shift(b, type = "lead") == "g2", .N]
    ## [1] 1
    

    这基本上是将a 与移位的a 列进行比较,同时检查b 列是否等于g1 并且移位的b 列是否等于g2。您需要 CRAN 上最新的 data.table 版本才能使其正常工作。


    使用dplyr 可以在这些行中有所作为

    library(dplyr)
    df %>%
      filter(a == lead(a) & b == "g1" & lead(b) == "g2") %>%
      count()
    # Source: local data table [1 x 1]
    # 
    #       n
    #   (int)
    # 1     1
    

    或以 R 为基数

    sum(with(df, a == c(tail(as.character(a), -1), NA) & b == "g1" & c(tail(as.character(b), -1), NA) == "g2"))
    ## [1] 1
    

    【讨论】:

      【解决方案2】:

      另一种选择:

      数据:

      df <- read.table(header=T, text=' a  b      c
      1  x g1  date1
      2  x g1  date2
      3  y g2  date3
      4  y g3  date4
      5  y g4  date5
      6  z g1  date6
      7  z g2  date7
      8  x g4  date8
      9  y g1  date9
      10 y g3 date10', stringsAsFactors=F)
      

      解决方案:

      library(dplyr) #for lag
      #df$a == lag(df$a) checks the equality in consecutive rows in a
      #the rest of the code checks the order of g2 and g1 in consecutive rows
      df$out <- df$a == lag(df$a) &   grepl(paste('g2','g1'), paste(df$b, lag(df$b)))
      

      输出:

      > df
         a  b      c   out
      1  x g1  date1 FALSE
      2  x g1  date2 FALSE
      3  y g2  date3 FALSE
      4  y g3  date4 FALSE
      5  y g4  date5 FALSE
      6  z g1  date6 FALSE
      7  z g2  date7  TRUE
      8  x g4  date8 FALSE
      9  y g1  date9 FALSE
      10 y g3 date10 FALSE
      

      还有

      sum(df$out)
      [1] 1
      

      【讨论】:

        【解决方案3】:

        你可以这样做。

        result <- NULL
        for (i in 1:NROW(df)){result <- c(result, df$a[i]==df$a[i-1] & df$b[i]=="g2" & df$b[i-1]=="g1")}
        length(which(result))
        # [1] 1
        

        这是数据。

        a <- c("x", "x", "y", "y", "y", "z", "z", "x", "y", "y")
        b <- c("g1", "g1", "g2", "g3", "g4", "g1", "g2", "g4", "g1", "g3")
        c <- paste("date", 1:10, sep = "")
        df <- as.data.frame(cbind(a,b,c))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-27
          • 2019-07-14
          • 1970-01-01
          相关资源
          最近更新 更多