【问题标题】:Remove duplicate element within a row in a specific column删除特定列中行内的重复元素
【发布时间】:2021-10-01 15:14:06
【问题描述】:

我有一个数据框,例如 ;

COL1  COL2
A,A,A 2
B     1
C,C   4
D,D,D 1
A     4
F     2
C,C   1 

我想先删除COL1 中的重复项并得到:

COL1  COL2
A     2
B     1
C     4
D     1
A     4
F     2
C     1 

然后将相同的COL1 字母COL2 相加,得到:

COL1  COL2
A     6
B     1
C     5
D     1
F     2

请问有人有想法吗? 如果有帮助,这里是数据框:

structure(list(COL1 = structure(c(2L, 3L, 4L, 5L, 1L, 6L, 4L), .Label = c("A", 
"A,A,A", "B", "C,C", "D,D,D", "F"), class = "factor"), COL2 = c(2, 
1, 4, 1, 4, 2, 1)), class = "data.frame", row.names = c(NA, -7L
))

【问题讨论】:

    标签: r regex dataframe dplyr subset


    【解决方案1】:

    基本 R 选项

    aggregate(
      COL2 ~ .,
      transform(
        df,
        COL1 = gsub(",.*", "", COL1)
      ),
      sum
    )
    

    给予

      COL1 COL2
    1    A    6
    2    B    1
    3    C    5
    4    D    1
    5    F    2
    

    【讨论】:

      【解决方案2】:

      trimws 的选项

      library(dplyr)
      df1 %>%
           group_by(COL1 = trimws(COL1, whitespace = ",.*")) %>% 
           summarise(COL2 = sum(COL2), .groups = 'drop')
      # A tibble: 5 x 2
        COL1   COL2
        <chr> <dbl>
      1 A         6
      2 B         1
      3 C         5
      4 D         1
      5 F         2
      

      【讨论】:

        【解决方案3】:

        您可以使用separate_rows 将逗号上的数据拆分为不同的行,只保留唯一值并聚合。

        library(dplyr)
        library(tidyr)
        
        df %>%
          mutate(row = row_number()) %>%
          separate_rows(COL1, sep = ',\\s*') %>%
          distinct(row, COL1, .keep_all = TRUE) %>%
          group_by(COL1) %>%
          summarise(COL2 = sum(COL2, na.rm = TRUE))
        
        #  COL1   COL2
        #  <chr> <dbl>
        #1 A         6
        #2 B         1
        #3 C         5
        #4 D         1
        #5 F         2
        

        【讨论】:

          【解决方案4】:

          一个选项可能是:

          df %>%
           group_by(COL1 = gsub(",.*$", "", COL1)) %>%
           summarise(COL2 = sum(COL2))
          
            COL1   COL2
            <chr> <dbl>
          1 A         6
          2 B         1
          3 C         5
          4 D         1
          5 F         2
          

          如果每行可能存在多个非重复元素:

          df %>%
           group_by(COL1 = sapply(strsplit(as.character(COL1), ",", fixed = TRUE), function(x) toString(unique(x)))) %>%
           summarise(COL2 = sum(COL2))
          

          【讨论】:

            【解决方案5】:

            我们可以使用substring

            library(dplyr)
            df %>% 
                mutate(COL1 = substring(COL1, 1,1)) %>% 
                group_by(COL1) %>% 
                summarise(COL2 = sum(COL2))
            
            

            输出:

              COL1   COL2
              <chr> <dbl>
            1 A         6
            2 B         1
            3 C         5
            4 D         1
            5 F         2
            

            【讨论】:

              【解决方案6】:

              你可以str_extract基于[:alpha:]{1},这将extract序列中的第一个字母,然后继续group_bysummarise

              data %>% 
                      mutate(COL1 = str_extract(COL1,pattern = "[:alpha:]{1}")) %>% 
                      group_by(COL1) %>% 
                      summarise(COL2 = sum(COL2, na.rm = TRUE))
              

              它给出以下输出,

              # A tibble: 5 x 2
                COL1   COL2
                <chr> <dbl>
              1 A         6
              2 B         1
              3 C         5
              4 D         1
              5 F         2
              

              【讨论】:

                【解决方案7】:

                您也可以使用splitstackshape 中的cSplit

                df %>% cSplit("COL1", ",", "long") %>%
                  unique() %>% group_by(COL1) %>% summarise(COL2 = sum(COL2))
                
                  COL1   COL2
                  <chr> <dbl>
                1 A         6
                2 B         1
                3 C         5
                4 D         1
                5 F         2
                

                【讨论】:

                  【解决方案8】:

                  通过在BaseR 中使用aggregate 函数,

                  setNames(
                      aggregate(df[,2] ,list(sub(",.*","",df[,1])),sum)
                      , c("COL1","COL2"))
                  

                  给予,

                    COL1 COL2
                  1    A    6
                  2    B    1
                  3    C    5
                  4    D    1
                  5    F    2
                  

                  【讨论】:

                    【解决方案9】:

                    基础 R 解决方案:

                    with(
                      df, 
                      aggregate(
                        list(COL2 = COL2), 
                        by = list(COL1 = gsub(
                          "^(\\w).*", 
                          "\\1", 
                          COL1
                          )
                        ), 
                        FUN = sum
                      )
                    )
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2019-08-02
                      • 2011-03-25
                      • 2020-01-19
                      • 1970-01-01
                      • 2018-05-02
                      • 2014-07-06
                      • 2020-07-08
                      相关资源
                      最近更新 更多