【问题标题】:Rearrange rows and calculate mode in R by creating a new variable通过创建新变量在 R 中重新排列行并计算模式
【发布时间】:2021-10-11 20:56:37
【问题描述】:

我有一个包含两列“ID”和“CODCOM”的数据集,大约有 100 万行。第一列“ID”包含重复值。

ID CODCOM
10000 12
101010 14
201020 11
201020 11
201020 12
324032 43
324032 43
324032 43
405044 51
323032 21

我想将“ID”重复值分组到不同的组中,然后计算每个组的模式,之后我想用相关的模式值创建一个新列。像这样的:

ID CODCOM NEW_COL
10000 12 12
101010 14 14
201020 11 11
201020 11 11
201020 12 11
324032 43 43
324032 43 43
324032 43 43
405044 51 51
323032 21 43

我怎样才能以简单的方式做到这一点?

非常感谢您提供的任何帮助。

【问题讨论】:

标签: r summary


【解决方案1】:

一种 dplyr 方法,我将数据加入到其自身的版本中,该版本仅具有最常见的 CODCOM 值(或首次出现与关系)。

library(dplyr)
df1 %>%
  left_join(
    df1 %>%
      group_by(ID) %>%
      count(mode = CODCOM, sort = TRUE) %>%
      slice(1),
    by = "ID"
  )


       ID CODCOM mode n
1   10000     12   12 1
2  101010     14   14 1
3  201020     11   11 2
4  201020     11   11 2
5  201020     12   11 2
6  324032     43   43 3
7  324032     43   43 3
8  324032     43   43 3
9  405044     51   51 1
10 323032     21   21 1

【讨论】:

    【解决方案2】:

    请使用data.table 包找到以下一种解决方案:

    REPREX

    • 代码
    library(data.table)
    
    
    # Function to compute mode
    mode_compute <- function(x) {
      uniqx <- unique(x)
      uniqx[which.max(tabulate(match(x, uniqx)))]
    }
    
    # Compute mode by ID
    DT[ , MODE := mode_compute(CODCOM), by = ID]
    
    • 输出
    DT
    #>         ID CODCOM MODE
    #>  1:  10000     12   12
    #>  2: 101010     14   14
    #>  3: 201020     11   11
    #>  4: 201020     11   11
    #>  5: 201020     12   11
    #>  6: 324032     43   43
    #>  7: 324032     43   43
    #>  8: 324032     43   43
    #>  9: 405044     51   51
    #> 10: 323032     21   21
    
    • 数据:
    # Data
    DT <- data.table(ID = c("10000", "101010", "201020", "201020", "201020",
                     "324032", "324032", "324032", "405044", "323032"),
                     CODCOM = c(12, 14, 11, 11, 12, 43, 43, 43, 51, 21))
    DT
    #>         ID CODCOM
    #>  1:  10000     12
    #>  2: 101010     14
    #>  3: 201020     11
    #>  4: 201020     11
    #>  5: 201020     12
    #>  6: 324032     43
    #>  7: 324032     43
    #>  8: 324032     43
    #>  9: 405044     51
    #> 10: 323032     21
    

    reprex package (v0.3.0) 于 2021 年 10 月 11 日创建

    【讨论】:

      【解决方案3】:

      如果我理解正确的话:我们可以group_byID然后使用模式函数的summarisemode

      如果您不想summarise,您可以改用mutate(将保留所有行)!

      library(dplyr)
      
      mode <- function(codes){
        which.max(tabulate(codes))
      }
      
      df %>% 
        as_tibble() %>% 
        group_by(ID) %>% 
        summarise(NEW_COL = mode(CODCOM))
      
            ID NEW_COL
         <int>   <int>
      1  10000      12
      2 101010      14
      3 201020      11
      4 323032      21
      5 324032      43
      6 405044      51
      

      【讨论】:

        【解决方案4】:

        基础 R 解决方案:

        # Option 1 using TarJae's mode function:
        # Apply the function groupwise, store result as vector:
        # NEW_COL => integer vector
        df$NEW_COL <- with(
          df,
          ave(
            CODCOM,
            ID,
            FUN = function(x){
              which.max(tabulate(x))
            }
          )
        )
        
        # Option two:
        # Function to calculate the mode of a vector: 
        # mode_statistic => function()
        mode_statistic <- function(x){
          # Calculate the mode: res => vector
          res <- names(
            head(
              sort(
                table(
                  x
                ),
                decreasing = TRUE
              ),
              1
            )
          )
          # Explicitly define returned object: character vector => env
          return(res)
        }
        
        # Apply the function groupwise, store result as vector:
        # NEW_COL => integer vector
        df$NEW_COL <- with(
          df,
          ave(
            CODCOM,
            ID,
            FUN = function(x){
              as.integer(
                mode_statistic(x)
              )
            }
          )
        )
        

        【讨论】:

          猜你喜欢
          • 2018-10-28
          • 1970-01-01
          • 2016-10-19
          • 2020-04-25
          • 1970-01-01
          • 1970-01-01
          • 2020-01-15
          • 2015-08-17
          • 1970-01-01
          相关资源
          最近更新 更多