38

I have a dataframe with a bunch of columns that I need to convert to the numeric type. I have written the following code to try to do this, however it is saying the replacement has 0 rows.

instanceconvert <- colnames(regmodel[7:262])

for (i in instanceconvert)
{
  regmodel$i <- as.numeric(regmodel$i)
}

Any help would be appreciated.

Scohen
  • 395
  • 1
  • 3
  • 5
  • The reason this is not working is that you are telling R to look for an object named `i` inside of `regmodel`. Inside your loop, `i` is the column itself, not the name of the column anyway. – Señor O Oct 02 '13 at 20:40
  • And don't forget 8.2.1 in the R Inferno: www.burns-stat.com/pages/Tutor/R_inferno.pdf – Henrik Oct 02 '13 at 20:42
  • 1
    See also http://stackoverflow.com/a/12727871/636656 – Ari B. Friedman Oct 02 '13 at 20:51

7 Answers7

60

You can use sapply for this:

dat <- sapply( dat, as.numeric )

If not every column needs converting:

library( taRifx )
dat <- japply( dat, which(sapply(dat, class)=="character"), as.numeric )
Ari B. Friedman
  • 71,271
  • 35
  • 175
  • 235
  • 16
    It may be useful to note that the class of `dat` is now `matrix`. `dat <- as.data.frame(sapply(dat, as.numeric)` allows for easier replacement. – Robert Yi Dec 22 '17 at 19:29
10

Combining the answer by @Andrii with the comment by @RobertYi, my short suggestion is

df[] <- sapply(df, as.numeric)

This ensures that the result stays as data frame and preserves column names (thanks, @krassowski).

bers
  • 4,817
  • 2
  • 40
  • 59
9

Here is quick solution from other question:

df[] <- lapply(df, function(x) as.numeric(as.character(x)))

Reference: Change all columns from factor to numeric in R

Andrii
  • 2,843
  • 27
  • 33
5

As SenorO pointed out, the reason your original code does not work is that $i will not evaluate i to find out it's current value. You should instead access and assign to the column using double brackets, which work when i is a name or index number:

for (i in instanceconvert)
{
  regmodel[[i]] <- as.numeric(regmodel[[i]])
}

Following Ari's approach, you can get rid of the loop:

regmodel[,instanceconvert] <- 
    lapply(regmodel[,instanceconvert,drop=FALSE],as.numeric)

You could also do this with your range, 7:262, in place of "instanceconvert", since you can access/assign by name or column number.

Frank
  • 66,179
  • 8
  • 96
  • 180
3

A fast a dirty way to do it, especially if you have variables all over that need converting, which would mean a lot of conversion code is to write the file out and read it back in again using something like write.csv/read.csv

write.csv(regmodel, file="regmodel.csv")
read.csv(file="regmodel.csv")
Keith Bailey
  • 61
  • 1
  • 5
3

Just pass the columns you want as a data frame d into the following:

data.frame(apply(d, 2, as.numeric))

This goes column by column and converts each into a numeric. Then just change your row-names and column-names accordingly.

bmc
  • 817
  • 1
  • 12
  • 23
1

Along with all of these approaches, if you have character/numeric/date type columns and want to convert (type of) them according to their value, the following may be useful:

type.convert(df, as.is = TRUE)