15

In R, is there a function like read.csv that reads in files where the headers are on the left (or right) as opposed to the top and the data is organized from left to right?

So the data would look like:

var1,1,2,3,4,5

Looking at the documentation for read.table and read.csv, nothing seems to pop out. The best option I see using those functions is to use read.table and then construct another table whose columns are the rows of the original data and so forth.

Ricardo Oliveros-Ramos
  • 4,322
  • 2
  • 25
  • 42
Jon Claus
  • 2,862
  • 4
  • 22
  • 33
  • Can you give a minimal 2 or 3 line example of how your text data looks? Do you mean each line is just like: `var1,1,2,3,4,5`? – thelatemail Jun 25 '13 at 02:33
  • Yes, exactly like that. So the header in this case is the left most column. – Jon Claus Jun 25 '13 at 02:45
  • 2
    *if* all the variables are numeric then you can do as you suggested; `x <- read.csv(...); y <- setNames(as.data.frame(t(x[,-1])),as.character(x[,1]))` – Ben Bolker Jun 25 '13 at 02:52
  • That seems to work fairly well, with one exception. If the first row is supposed to be labels for the data, for example the year number, `read.csv` will append an `X` to each value. This is easily fixed manually though. Thanks. – Jon Claus Jun 25 '13 at 02:54
  • Try using `read.table`, since `read.csv` is just a wrapper for that function with some of the arguments "hard coded". For example, `header = FALSE` might be helpful. – joran Jun 25 '13 at 03:20
  • @BenBolker's comment is great. Would be convenient if `read.csv` or `readr::read_csv` had a logical `transpose=F` default that when true would become a wrapper for something like this! – Michael Roswell Jun 19 '19 at 20:06

1 Answers1

25

Let's say your file is called 'data.csv' and it contains:

var1,1,2,3,4,5,6
var2,2.1,3.9,4.6,5.2,6.1
var3,M,F,M,F,M,M

Note var1 and var3 have 6 values but var2 has only 5. So, the idea is to read the data, transpose it and then use read.csv.

read.tcsv = function(file, header=TRUE, sep=",", ...) {

  n = max(count.fields(file, sep=sep), na.rm=TRUE)
  x = readLines(file)

  .splitvar = function(x, sep, n) {
    var = unlist(strsplit(x, split=sep))
    length(var) = n
    return(var)
  }

  x = do.call(cbind, lapply(x, .splitvar, sep=sep, n=n))
  x = apply(x, 1, paste, collapse=sep) 
  out = read.csv(text=x, sep=sep, header=header, ...)
  return(out)

}

Then, you can do:

read.tcsv("data.csv")

  var1 var2 var3
1    1  2.1    M
2    2  3.9    F
3    3  4.6    M
4    4  5.2    F
5    5  6.1    M
6    6   NA    M
Ricardo Oliveros-Ramos
  • 4,322
  • 2
  • 25
  • 42