1
votes

Is it possible to use read.table to read a data set in which variables and numbers appear in the same column? Here is an example that does not work, followed by matrix which does work:

aa <- 10
bb <- 20

my.data1 <- read.table(text = '
    aa   0
    0    bb
', header = FALSE, stringsAsFactors = FALSE)
my.data1

# matrix returns desired output
my.data2 <- matrix(c(  aa,   0,
                        0,  bb  ), nrow = 2, ncol = 2, byrow = TRUE)    
my.data2
#     [,1] [,2]
# [1,]   10    0
# [2,]    0   20

My guess is that text converts aa and bb to text, but can this be avoided while still using read.table?

str(my.data1)
'data.frame':   2 obs. of  2 variables:
 $ V1: chr  "aa" "0"
 $ V2: chr  "0" "bb"
1
This is kind of unclear. In general, though, any atomic object can only have one class, this includes vectors, matrices, and a variable in a data.frame, so you can't have both numeric and character values in any of those structures. - Thomas
Thanks, Thomas. Consider posting that as the answer. Although, why does it work when using matrix? - Mark Miller

1 Answers

2
votes

The text argument to the read.table function doesn't convert your input to a character string, it's the (single) quotes that create a string literal or string constant as the R documentation for quotes (do ?Quotes in R) explains:

Single and double quotes delimit character constants. They can be used interchangeably but double quotes are preferred (and character constants are printed using double quotes), so single quotes are normally only used to delimit character constants containing double quotes.

The aa and bb in the matrix command are symbols in R as they are not quoted and the interpreter will find their values in the global environment.

So to answer your question: no, it's not possible to do this unless you use a function like sprintf to subsitute the values of aa and bb in the string. For example:

my.data1 <- read.table(text = sprintf('
    %f   0
    0    %f', aa, bb), header = FALSE, stringsAsFactors = FALSE)

But this is not something that would be very common to do!