JC3019
JC3019

Reputation: 383

Creating new vector that represents the count

I want to create a vector of counts in the following way:

say my vector is

x <- c(1,1,1,1,2)

which represents a categorical variable. I want a second vector of the form

x1 <- c(4,4,4,4,1)

which represents the count at each level. e.g. 4 occurrences of level 1, and 1 occurrence of level 2.

I have tried

r <- range(x) ; table(factor(x, levels = r[1]:r[2])) 
tabulate(factor(x, levels = min(x):max(x)))
table(x)

Upvotes: 6

Views: 204

Answers (5)

akrun
akrun

Reputation: 886938

An option with tapply from base R.

v1 <- tapply(x, x, FUN = length)
rep(as.integer(v1), v1)
#[1] 4 4 4 4 1

NB: It is a dupe

Upvotes: 0

Ronak Shah
Ronak Shah

Reputation: 388797

We can use tabulate or table along with rep

x1 <- tabulate(x)
rep(x1,x1)
#[1] 4 4 4 4 1

x1 <- table(x)
as.integer(rep(x1, x1))
#[1] 4 4 4 4 1

Upvotes: 1

Cole
Cole

Reputation: 11255

This uses ave to group by each value. This would likely be better if your vector is definitely an integer type.

x <- c(1,1,1,1,2)

ave(x, x,  FUN = length)
[1] 4 4 4 4 1

Equivalents in data.table and dplyr:

library(data.table)
data.table(x)[, n:= .N, by = 'x'][]

   x n
1: 1 4
2: 1 4
3: 1 4
4: 1 4
5: 2 1

library(dplyr)
library(tibble)
tibble::enframe(x, name = NULL)%>%
  add_count(value)

##or

x%>%
  tibble::enframe(name = NULL)%>%
  group_by(value)%>%
  mutate(n = n())%>%
  ungroup()

# A tibble: 5 x 2
  value     n
  <dbl> <int>
1     1     4
2     1     4
3     1     4
4     1     4
5     2     1

Upvotes: 5

ZiGaelle
ZiGaelle

Reputation: 744

If you do it like this:

x = c(1,1,1,1,2)
x1 = as.vector(table(x)[x])

You obtain the vector you wanted:

[1] 4 4 4 4 1

Upvotes: 2

NelsonGon
NelsonGon

Reputation: 13309

We can use fct_count from forcats which has a sort argument too:

x <- as.factor(x)
forcats::fct_count(x)
# A tibble: 2 x 2
  f         n
  <fct> <int>
1 1         4
2 2         1

Upvotes: 0

Related Questions