【问题标题】:Count occurrence of a value within a data frame within the rows above it计算其上方行内数据框中值的出现次数
【发布时间】:2018-06-12 14:57:31
【问题描述】:

我正在尝试找到一种方法来创建一个矩阵,该矩阵计算数据框每一行的值。我希望它能够识别数据框每一行中的值,并计算该值在该行上方的所有行中出现的次数(而不是整个数据框)。

同一值永远不会在数据框的单行中出现多次。

例如:

# df:

a b c
1 2 3
3 4 5
3 2 6
7 8 9
8 3 6

矩阵结果:

0 0 0(没有出现任何 df 值,因为上面没有行)

1 0 0(上面出现过3次,其他都没有出现过)

2 1 0(3 上面出现过两次,2 上面出现过一次,6 没有出现过)

0 0 0(上面的行中没有出现任何df值)

1 3 1(8出现过一次,3出现过3次,6出现过一次)

【问题讨论】:

    标签: r count


    【解决方案1】:

    这是一种方法:

    # convert to a vector
    x = as.vector(t(as.matrix(df)))
    
    # get counts of each unique element (in the right place)
    # and add them up
    res = rowSums(sapply(unique(x), function(z) {
      r = integer(length(x))
      r[x == z] = 0:(sum(x == z) - 1)
      return(r)
    }))
    
    # convert to matrix
    res = matrix(res, ncol = ncol(df), byrow = T)
    res
    #      [,1] [,2] [,3]
    # [1,]    0    0    0
    # [2,]    1    0    0
    # [3,]    2    1    0
    # [4,]    0    0    0
    # [5,]    1    3    1
    

    使用这些数据:

    df = read.table(text = "
    a b c
    1 2 3
    3 4 5
    3 2 6
    7 8 9
    8 3 6", header = T)
    

    【讨论】:

      【解决方案2】:

      其他三种方法:

      1) 以 R 为基数:

      temp <- stack(df)[c(outer(c(0,5,10), 1:5, '+')),]
      temp$val2 <- with(temp, ave(values, values, FUN = seq_along)) - 1
      df2 <- unstack(temp, val2 ~ ind)
      

      给出:

      > df2
        a b c
      1 0 0 0
      2 1 0 0
      3 2 1 0
      4 0 0 0
      5 1 3 1
      

      2) 与data.table:

      library(data.table)
      melt(setDT(df)[, r := .I],
           id = 'r')[order(r), val2 := rowid(value) - 1
                     ][, dcast(.SD, rowid(variable) ~ variable, value.var = 'val2')
                       ][, variable := NULL][]
      

      给出相同的结果。

      3) 使用tidyverse

      library(dplyr)
      library(tidyr)
      df %>% 
        mutate(r = row_number()) %>% 
        gather(k, v, -4) %>% 
        arrange(r) %>% 
        group_by(v) %>% 
        mutate(v2 = row_number() - 1) %>% 
        ungroup() %>% 
        select(r, k, v2) %>% 
        spread(k, v2)
      

      当然,这也给出了相同的结果。

      【讨论】:

        【解决方案3】:

        这是另一个解决方案:

        df = read.table(text = "a b c
                        1 2 3
                        3 4 5
                        3 2 6
                        7 8 9
                        8 3 6", header = T)
        
        elements = sort(unique(unlist(df)))
        frequency = sapply(elements, # for each element 
                           function(element) {apply(df == element, 1, sum)}) # Sum the number of occurances per row
        #       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
        # [1,]    1    1    1    0    0    0    0    0    0
        # [2,]    0    0    1    1    1    0    0    0    0
        # [3,]    0    1    1    0    0    1    0    0    0
        # [4,]    0    0    0    0    0    0    1    1    1
        # [5,]    0    0    1    0    0    1    0    1    0
        
        
        results = df
        for(i in 1:nrow(df)){
          for(j in 1:ncol(df))
            results[i,j] = sum(frequency[1:i-1, # Sum the prevoius rows occurances  
                                         which(df[i,j] == elements)]) # Of the same element
        }
        # a b c
        # 1 0 0 0
        # 2 1 0 0
        # 3 2 1 0
        # 4 0 0 0
        # 5 1 3 1
        

        【讨论】:

          【解决方案4】:

          另一个...为了好玩

          out<-matrix(1,nrow = nrow(df),ncol = ncol(df))
          for(i in 1:nrow(df)){
            out[i,]<-sapply(1:ncol(df),function(z) sum(unlist(df[0:(i-1),]) %in% df[i,z]))
          }
          
          out
               [,1] [,2] [,3]
          [1,]    0    0    0
          [2,]    1    0    0
          [3,]    2    1    0
          [4,]    0    0    0
          [5,]    1    3    1
          

          【讨论】:

            【解决方案5】:

            我知道我们不应该用“谢谢”发表评论,但谢谢大家。我已将 Brian 的回复标记为最有用的,因为我对 R 还很陌生,他是我可以一直遵循的示例,而无需查找任何内容。不过,我会很高兴了解您分享的所有其他方式和新的(对我而言)功能/方法。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-01-11
              • 2021-08-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多