buhtz
buhtz

Reputation: 12172

How to rbind multiple tables

I want to bind more then two tables together with rbind() in R.

Based on my experience with R-problems I am sure the solution is easy. But I don't get it. Please see this example data

# create sample data
set.seed(0)
df <- data.frame(A = 0,
                 B1 = sample(c(1:3, NA), 10, replace=TRUE),
                 B2 = sample(c(1:3, NA), 10, replace=TRUE),
                 B3 = sample(c(1:3, NA), 10, replace=TRUE),
                 C = 0)

# names of relevant objects
n <- names(df)[startsWith(names(df), 'B')]

You see (in n) I just want to use a selection of objects of a data.frame.

No I create tables out of them and bind there rows to gether for better presentation.

t1 <- table(df$B1, useNA="always")
t2 <- table(df$B2, useNA="always")
t3 <- table(df$B3, useNA="always")

# this is a workaround
print( rbind(t1, t2, t3) )

But I would like to make this code more easier because my real data has a lot more tables then three.

This here doesn't work

# this is what I "want" but doesn't work
print( rbind( table(df[,n])) )

# another try
do.call('rbind', list(table(df[,n])))

Where is the error in my thinking?

Upvotes: 2

Views: 843

Answers (2)

Onyambu
Onyambu

Reputation: 79238

You can do:

table(stack(df[n])[2:1],useNA = 'always')[-4,]
    values
ind  1 2 3 <NA>
  B1 1 2 3    4
  B2 3 3 2    2
  B3 3 3 1    3

well if you do not want to reverse by using [2:1], you can transpose:

t(table(stack(df[n]),useNA = 'always'))[-4,]
    values
ind  1 2 3 <NA>
  B1 1 2 3    4
  B2 3 3 2    2
  B3 3 3 1    3

if you want it as a data.frame:

as.data.frame.matrix(table(stack(df[n])[2:1],useNA = 'always')[-4,])
   1 2 3 NA
B1 1 2 3  4
B2 3 3 2  2
B3 3 3 1  3

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388992

We can lapply over selected columns and then use table on individual of them and join them together using rbind

do.call("rbind", lapply(df[n], function(x) table(x, useNA = "always")))

#   1 2 3 <NA>
#B1 1 2 3    4
#B2 3 3 2    2
#B3 3 3 1    3

This can also be done using apply with margin = 2 (column-wise)

t(apply(df[n], 2, function(x) table(x, useNA = "always")))

#   1 2 3 <NA>
#B1 1 2 3    4
#B2 3 3 2    2
#B3 3 3 1    3

Upvotes: 2

Related Questions