Cina
Cina

Reputation: 10199

Counting the elements in rows and map to column in r

I would like summarize my data by counting the entities and create counting_column for each entity. let say: df:

id   class
1     A
1     B
1     A
1     A
1     B
1     c
2     A
2     B
2     B
2     D

I want to create a table like

id  A  B  C  D
1   3  2  1  0
2   1  2  0  1

How can I do this in R using apply function?

Upvotes: 0

Views: 377

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 270055

This seems like a very strange requirement but if you insist on using apply then the function count counts the number of rows for which id equals x and class equals y. It is applied to every combination of id and class to get a using nested apply calls. Finally we add the row and column names.

uid <- unique(DF$id)
uclass <- unique(DF$class)

count <- function(x, y, DF) sum(x == DF$id & y == DF$class)
a <- apply(matrix(uclass), 1, function(u) apply(matrix(uid), 1, count, u, DF))
dimnames(a) <- list(uid, uclass)

giving:

> a
  A B c D
1 3 2 1 0
2 1 2 0 1

Note

We used this for DF

Lines <- "id   class
1     A
1     B
1     A
1     A
1     B
1     c
2     A
2     B
2     B
2     D"
DF <- read.table(text = Lines, header = TRUE)

Upvotes: 1

Zheyuan Li
Zheyuan Li

Reputation: 73385

df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), 
class = structure(c(1L, 2L, 1L, 1L, 2L, 3L, 1L, 2L, 2L, 4L
), .Label = c("A", "B", "C", "D"), class = "factor")), .Names = c("id", 
"class"), class = "data.frame", row.names = c(NA, -10L))

with(df, table(id, class))
#   class
#id  A B C D
#  1 3 2 1 0
#  2 1 2 0 1

xtabs(~ id + class, df)
#   class
#id  A B C D
#  1 3 2 1 0
#  2 1 2 0 1

tapply(rep(1, nrow(df)), df, length, default = 0)
#   class
#id  A B C D
#  1 3 2 1 0
#  2 1 2 0 1

Upvotes: 3

Related Questions