Как рассчитать сумму запятой, разделенной во 2-м столбце - PullRequest
0 голосов
/ 10 ноября 2018
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

Ответы [ 3 ]

0 голосов
/ 10 ноября 2018

Мы можем использовать 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))
0 голосов
/ 10 ноября 2018

, используя этот метод, я получаю asnwer sapply (sm2 $ y, function (i) sum (as.numeric (i)))

0 голосов
/ 10 ноября 2018

Попробуйте это:

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.


Если у вашего кадра factor s вместо строк, вместо этого используйте

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...