pat
pat

Reputation: 627

Method to print long R dataframes with row labels as table

Suppose I have some very long dataframe of information with row labels. If I try to print the object using kable, or any standard table, it does not print neatly. I desire to reformat the data into a table, while still retaining the rownames as column row labels. As an example, imagine something like a dataframe of letters that was 1000 lines as long as below. If I printed it as a pdf table, it would consume about a tenth of the width of a page, and several pages.

> eg <- data.frame(LETTERS,seq(26),seq(26))
   LETTERS seq.26. seq.26..1
1        A       1         1
2        B       2         2
3        C       3         3
4        D       4         4
..................
24       X      24        24
25       Y      25        25
26       Z      26        26

I would like to have some tabular object to print neatly with knitr, such as,

A 1 1 F 6 6   K 11 11 ...
B 2 2 G 7 7   L 12 12 ...
C 3 3 H 8 8   M 13 13 ...
D 4 4 I 9 9   N 14 14 ...    
E 5 5 J 10 10 O 15 15 ...  Z 26 26

I omitted some of the data to save on typing. But any method to get this type of tabular output from the original dataframe is desirable. It seems like there should be an easy task, using something like redimensioning the dataframe as a matrix, but it would lose row label information. I couldn't find any examples. Any ideas?

edit1: assuming I have a column of the row labels already is fine (as in the LETTERS example). edit2: I tried to use a simple matrix re-dimensioning of the data and it does close to what I would like, but the row to column labels lose their relationships. The other thing to point out is that I still would like to have an object printed (via kable like tabular knitr method) that would highlight the labels distinctly from the value columns.

e.g.

> matrix(as.matrix(eg),4,6)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,] "A"  "E"  "1"  "5"  "1"  "5" 
[2,] "B"  "F"  "2"  "6"  "2"  "6" 
[3,] "C"  "G"  "3"  "7"  "3"  "7" 
[4,] "D"  "H"  "4"  "8"  "4"  "8" 

Upvotes: 0

Views: 698

Answers (1)

Molx
Molx

Reputation: 6921

Considering your sample data:

eg<- data.frame(LETTERS[1:26],seq(26),seq(26), stringsAsFactors = FALSE)

You can create a matrix with subsets of the desired number of rows, and then cbind them all together:

outrows <- 4

output <- do.call(cbind, 
              sapply(1:((nrow(eg)/outrows)+1), 
                     function(i) eg[seq(outrows*i-(outrows-1), outrows*i),]))

output[is.na(output)] <- "" #Making sure nasty NA's don't polute our output

You might be interested in a result without quotes, so:

> print(output, quote = FALSE)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21]
[1,] A    1    1    E    5    5    I    9    9    M     13    13    Q     17    17    U     21    21    Y     25    25   
[2,] B    2    2    F    6    6    J    10   10   N     14    14    R     18    18    V     22    22    Z     26    26   
[3,] C    3    3    G    7    7    K    11   11   O     15    15    S     19    19    W     23    23                     
[4,] D    4    4    H    8    8    L    12   12   P     16    16    T     20    20    X     24    24                     

Or even (from here):

> write.table(format(output, justify="right"),  row.names=F, col.names=F, quote=F)
 A  1  1  E  5  5  I  9  9  M 13 13  Q 17 17  U 21 21  Y 25 25
 B  2  2  F  6  6  J 10 10  N 14 14  R 18 18  V 22 22  Z 26 26
 C  3  3  G  7  7  K 11 11  O 15 15  S 19 19  W 23 23         
 D  4  4  H  8  8  L 12 12  P 16 16  T 20 20  X 24 24         

Upvotes: 2

Related Questions