【问题标题】:How can I calculate the sum of comma separated in the 2nd column如何计算第二列中逗号分隔的总和
【发布时间】:2018-11-10 05:06:05
【问题描述】:
sm_agg
   Group.1                   x
1     1001                   8
2     1002               16, 8
3     1003                   8
4     1004                  16
5     1005 5.33333333333333, 8
6     1006                   4
7     1007                   4
8     1008                   4
9     1009    5.33333333333333
10    1010 8, 5.33333333333333
11    1011                8, 4
12    1012    5.33333333333333
13    1013 5.33333333333333, 8
14    1014                   8
15    1015    5.33333333333333
16    1016    5.33333333333333

我想变成这样

sm_agg
   Group.1                   x
1     1001                   8
2     1002                   24
3     1003                   8
4     1004                  16
5     1005                  13.3
6     1006                   4
7     1007                   4
8     1008                   4
9     1009    5.33333333333333
10    1010                13.3
11    1011                  12
12    1012    5.33333333333333
13    1013                 13.3
14    1014                   8
15    1015    5.33333333333333
16    1016    5.33333333333333

【问题讨论】:

    标签: r


    【解决方案1】:

    试试这个:

    sm_agg$x <- sapply(strsplit(sm_agg$x, "[ ,]+"), function(i) sum(as.numeric(i)))
    sm_agg
    #    Group.1         x
    # 1     1001  8.000000
    # 2     1002 24.000000
    # 3     1003  8.000000
    # 4     1004 16.000000
    # 5     1005 13.333333
    # 6     1006  4.000000
    # 7     1007  4.000000
    # 8     1008  4.000000
    # 9     1009  5.333333
    # 10    1010 13.333333
    # 11    1011 12.000000
    # 12    1012  5.333333
    # 13    1013 13.333333
    # 14    1014  8.000000
    # 15    1015  5.333333
    # 16    1016  5.333333
    

    解释:

    1. 对于单个条目,我们将其用一个或多个逗号/空格分隔:

      strsplit(sm_agg$x[2], "[, ]+")
      # [[1]]
      # [1] "16" "8" 
      
    2. 有了这个,我们想转换成数字并相加,所以

      as.numeric(strsplit(sm_agg$x[2], "[, ]+")[[1]])
      # [1] 16  8
      sum(as.numeric(strsplit(sm_agg$x[2], "[, ]+")[[1]]))
      # [1] 24
      
    3. 我们希望对每个元素都这样做,因此我们将 strsplit 输出提供给 sapply 匿名函数。


    如果你的框架有factors 而不是字符串,那么改为使用

    sapply(strsplit(as.character(sm_agg$x), "[ ,]+"), function(i) sum(as.numeric(i)))
    

    上次编辑

    我认为您的数据实际上是嵌入的list。当数据包含一个列表列时,它会像这样呈现(我觉得有点令人沮丧,但仍然......)。

    我会生成一些假数据来证明我认为你实际拥有的数据:

    sm2 <- data.frame(Group.1 = c("1001", "1002", "1003", "1005"))
    sm2$x <- list(c(8L), c(16L,8L), c(8L), c(16/3, 8))
    sm2
    #   Group.1                  x
    # 1    1001                  8
    # 2    1002              16, 8
    # 3    1003                  8
    # 4    1005 5.333333, 8.000000
    

    好的。当我们尝试strsplit 甚至as.character 时,事情就崩溃了,显然不是数字式的:

    as.character(sm2$x)
    # [1] "8"                      "c(16, 8)"               "8"                     
    # [4] "c(5.33333333333333, 8)"
    

    事实上,我们所要做的只是总结它们,因为它们已经是数字了。

    sapply(sm2$x, sum)
    # [1]  8.00000 24.00000  8.00000 13.33333
    

    如果偶然其中一个嵌套的东西实际上是character

    sm2$y <- list(c("8"), c(16L,8L), c(8L), c(16/3, 8))
    sm2
    #   Group.1                  x                  y
    # 1    1001                  8                  8
    # 2    1002              16, 8              16, 8
    # 3    1003                  8                  8
    # 4    1005 5.333333, 8.000000 5.333333, 8.000000
    

    这将导致我们的“简单”解决方案失败。

    sapply(sm2$y, sum)
    # Error in FUN(X[[i]], ...) : invalid 'type' (character) of argument
    

    幸运的是,我们可能有点过分,将字符串强制转换为数字,将数字强制转换为数字:

    sapply(sm2$y, function(i) sum(as.numeric(i)))
    # [1]  8.00000 24.00000  8.00000 13.33333
    sapply(sm2$x, function(i) sum(as.numeric(i)))
    # [1]  8.00000 24.00000  8.00000 13.33333
    

    【讨论】:

    • 当我应用这个我得到错误 > as.numeric(strsplit(sm_agg$x[2], "[, ]+")[[1]]) strsplit(sm_agg$x[ 2], "[, ]+") : 非字符参数 > sm_agg$x
    • 您的数据中有factors。将来,以明确的方式(例如dput(head(sm_agg)))呈现您的数据会阻止这种情况发生。请参阅我的编辑以了解解决方法。
    • >sapply(strsplit(as.character(sm_agg$x), "[,]+"), function(i) sum(as.numeric(i))) [1] 8.000000 NA 8.000000 16.000000 不适用 4.000000 4.000000 4.000000 5.333333 不适用 [11] 不适用 5.333333 不适用 8.000000 5.333333 5.333333
    • 您忘记了模式中的空格。该空间不是偶然的,也不是“代码风格偏好”。如果您想更清楚,请将"[ ,]+"(注意空格,引号内总共五个字符)替换为"[\\s,]+"(此处没有空格,\\s 包括空格和制表符)。
    • sapply(strsplit(as.character(sm_agg$x), "[ ,]+"), function(i) sum(as.numeric(i))) [1] 8.000000 NA 8.000000 16.000000 NA 4.000000 4.000000 4.000000 5.333333 NA [11] NA 5.333333 NA 8.000000 5.333333 5.333333 警告消息:1:在 FUN(X[[i]],...):强制引入的 NA 2:在 FUN(X[[i]] , ...) : 由强制 3 引入的 NA: In FUN(X[[i]], ...) : 由强制 4 引入的 NA: In FUN(X[[i]], ...) : 引入了 NA通过强制 5:在 FUN(X[[i]], ...) 中:强制引入的 NAs
    【解决方案2】:

    我们可以使用separate_rows 将逗号分隔的条目分隔到不同的行中,然后按组使用sum

    library(tidyverse)
    df %>%
      separate_rows(x, sep = ",") %>%
      group_by(Group.1) %>%
      summarise(x = sum(as.numeric(x)))
    
    
    #   Group.1  x
    #     <dbl> <dbl>
    # 1    1001  8   
    # 2    1002 24   
    # 3    1003  8   
    # 4    1004 16   
    # 5    1005 13.3 
    # 6    1006  4   
    # 7    1007  4   
    # 8    1008  4   
    # 9    1009  5.33
    #10    1010 13.3 
    #11    1011 12   
    #12    1012  5.33
    #13    1013 13.3 
    #14    1014  8   
    #15    1015  5.33
    #16    1016  5.33
    

    数据

    df <- structure(list(Group.1 = c(1001, 1002, 1003, 1004, 1005, 1006, 
     1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016), 
        x = structure(c(5L, 7L, 5L, 6L, 10L, 2L, 1L, 1L, 9L, 11L, 
     4L, 8L, 10L, 3L, 8L, 8L), .Label = c("                 4", 
      "                4", "                8", "             8, 4", 
     "       8", "      16", "   16, 8", "  5.33333333333333", 
     " 5.33333333333333", " 5.33333333333333, 8", " 8, 5.33333333333333"
     ), class = "factor")), .Names = c("Group.1", "x"), class = 
     "data.frame", row.names = c(NA, 
     -16L))
    

    【讨论】:

      【解决方案3】:

      使用这种方法我得到了 asnwer sapply(sm2$y, function(i) sum(as.numeric(i)))

      【讨论】:

        猜你喜欢
        • 2022-01-17
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多