Why are Xs added to data frame variable names when using read.csv?

read.table and read.csv have a check.names= argument that you can set to FALSE.

For example, try it with this input consisting of just a header:

> read.csv(text = "a,1,b")
[1] a  X1 b 
<0 rows> (or 0-length row.names)

versus

> read.csv(text = "a,1,b", check.names = FALSE)
[1] a 1 b
<0 rows> (or 0-length row.names)

It is surprising behavior, but I think we would need a reproducible example. Perhaps you have some invisible/special characters hiding in your file?

names(read.csv(textConnection(
"abcdefghijkl, a1,2x")))

behaves fine. Can you make an example along these lines that demonstrates your problem?

As described in the other answer, check.names=FALSE is a possible workaround. You can experiment with make.names to determine the behavior ...