1

I would like to determine the sum for each individual element in a vector.

For example, suppose I have the vector

x <- c(2,3,2,2,5,5,3,3)

and I want to find the sum for each element.

The answer would be something like

2: 6
3: 9
5: 10

This is because there are three 2's (2+2+2 or 2*), etc.

In other words, I want to essentially multiply the number times the number of times that element is found in the vector.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Andrew Hamel
  • 336
  • 1
  • 13

5 Answers5

3

Using base R tapply

tapply(x, x, sum)
# 2  3  5 
# 6  9 10 

If you need it as dataframe wrap it in stack

stack(tapply(x, x, sum))

#  values ind
#1      6   2
#2      9   3
#3     10   5

If you convert this to a dataframe then this becomes (How to sum a variable by group)

library(dplyr)
tibble::tibble(x) %>%
   group_by(x) %>%
   summarise(n = sum(x))

# A tibble: 3 x 2
#      x     n
#  <dbl> <dbl>
#1     2     6
#2     3     9
#3     5    10
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
2

A method with dplyr:

x <- c(2,3,2,2,5,5,3,3)

a = tibble(x)

a %>% count(x) %>% mutate(xn = x*n)

# A tibble: 3 x 3
      x     n    xn
  <dbl> <int> <dbl>
1     2     3     6
2     3     3     9
3     5     2    10
liuminzhao
  • 2,385
  • 17
  • 28
2

Lots of ways to do this. A couple of base approaches:

with(rle(sort(x)), data.frame(val = values, freq = lengths, prod = lengths*values))

  val freq prod
1   2    3    6
2   3    3    9
3   5    2   10

Or:

transform(as.data.frame(table(x), stringsAsFactors = FALSE), sum = as.numeric(x) * Freq)

  x Freq sum
1 2    3   6
2 3    3   9
3 5    2  10
Ritchie Sacramento
  • 29,890
  • 4
  • 48
  • 56
  • You need `prod = as.numeric(as.character(x)) * Freq)` OR `stringsAsFactors = F` in `as.data.frame()` in your second method. Nice answers. – Shree Jun 04 '19 at 01:31
  • 1
    @Shree - That was sloppy, thanks. But I think better to avoid having them as factors in the first place. – Ritchie Sacramento Jun 04 '19 at 01:34
1
library(tidyverse)

x <- c(2,3,2,2,5,5,3,3)
tibble(x) %>% 
count(x) %>% 
mutate(xn = x*n ) %>% 
pull(xn)
Marcio Rodrigues
  • 319
  • 1
  • 11
1

We can use rowsum from base R

rowsum(x, group = x)
#    [,1]
#2    6
#3    9
#5   10

Or with by

by(x, x, FUN = sum)

Or with split

sapply(split(x, x), sum)
#  2  3  5 
#  6  9 10 

Or another option with xtabs

xtabs(x1 ~ x, cbind(x1 = x, x))
#  2  3  5 
#  6  9 10 

Or with ave

unique(data.frame(x, Sum = ave(x, x, FUN = sum)))
#   x Sum
#1 2   6
#2 3   9
#5 5  10

Or using data.table

library(data.table)
data.table(grp = x, x=x)[, .(Sum = sum(x)), grp]
#   grp Sum
#1:   2   6
#2:   3   9
#3:   5  10
akrun
  • 874,273
  • 37
  • 540
  • 662