1

I want to add an extra row above what is row 1 of the following dataframe (i.e. above the labels a, b and Percent):

a<-c(1:5) 
b<-c(4,3,2,1,1) 
Percent<-c(40,30,20,10,10)  
df1<-data.frame(a,b,Percent)

These dataframes represent questions in an interview analysis I am doing, and I want to include the question descriptor above the row headers so I can easily identify which dataframe belongs to which question (i.e. "Age"). I have been using rbind to add rows, but is it possible to use this command above the row headers?

Thanks.

KT_1
  • 8,194
  • 15
  • 56
  • 68

3 Answers3

4

If it is just meta-data, you can add it as an attribute to the data.frame.

> attr(df1, "Question") <- "Age"
> attributes(df1)
$names
[1] "a"       "b"       "Percent"
$row.names
[1] 1 2 3 4 5
$class
[1] "data.frame"
$Question
[1] "Age"

If you want the question to be printed above the data.frame, you can define a Question class, that extends data.frame, and override the print method.

class(df1) <- c( "Question", class(df1) )
print.Question <- function( x, ... ) {
  if( ! is.null( attr(x, "Question") ) ) {
    cat("Question:", attr(x, "Question"), "\n")
  }
  print.data.frame(x)
}
df1

But that looks overkill: it may be simpler to just add a column.

> df1$Question <- "Age"
> df1
  a b Percent Question
1 1 4      40      Age
2 2 3      30      Age
3 3 2      20      Age
4 4 1      10      Age
5 5 1      10      Age
Vincent Zoonekynd
  • 31,893
  • 5
  • 69
  • 78
  • Thanks @Vincent Zoonekynd, however is it possible that "Age" can be added as the very first row (above the a, b and Percent) and not as a column? Thanks. – KT_1 Feb 14 '12 at 10:00
  • I have edited my answer to explain how to display the attribute by default. But it is meta-data, not data: for instance, if you save the data.frame to a CSV file, that will disappear -- that is why I prefer to add a column, even if it is redundant. – Vincent Zoonekynd Feb 14 '12 at 10:08
0

I wish this was a part of core R, but I hacked up a solution with Jason Bryer's Likert package using attributes to store column names, and having the likert function read these attributes and use them when plotting. It only works with that function though - there a function HMisc called label, but again none of the functions care about this (including the functions that show dataframes etc).

Here's a writeup of my hack http://reganmian.net/blog/2013/10/02/likert-graphs-in-r-embedding-metadata-for-easier-plotting/, with a link to the code.

Stian Håklev
  • 1,240
  • 2
  • 14
  • 26
0

rbind is really the only way to go but everything would switch to atomic data. For example:

cols <- c("Age", "Age", "Age")
df1 <- rbind(cols,df1)
str(df1)

Definitely agree with Vincent on this one, I do this quite frequently with survey data, if it's all in one data.frame I generally set a comment attribute on each element of the data.frame(), it's also useful when you perform multiple operations and you want to maintain reasonable colnames(df1). It's not good practice, but if this is for presentation you can always set check.names=F when you create your data.frame()

a<-c(1:5) 
b<-c(4,3,2,1,1) 
Percent<-c(40,30,20,10,10)  
df1<-data.frame(a,b,Percent)

comment(df1$a) <- "Q1a. This is a likert scale"
comment(df1$b) <- "Q1b. This is another likert scale"
comment(df1$Percent) <- "QPercent. This is some other question"

Then, if I "forget" what's in the columns, I can take a quick peak:

sapply(df1, comment)
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255