R How to effectively change datatype of an entire column from char to numeric/double in R

Viewed 41

I've tried couple of ways to change some selected columns of my data set from chr to num, but 2 columns have failed to changed while the remaining 14columns changed effectively. Viewing the dataset, I noticed that a row across both column has an exponential value in the form of (2.4999999999863576E-2) and (1.6000000000076398E-2) on row 5 of the picture.

Here are the code samples I've tried

animals[3:16] <- sapply(animals[3:16], as.numeric)

I found that column 12 and 13 refused to change bcos they include an exponent value

and I've also tried this belowScreenshot of viewing the animal dataset:

animals <- animals %>%
  mutate(animals[3:16], as.numeric) %>%
  str()

I also tried running: dput(head(animals, 20)) as suggested in the comment, and the output I got was:

structure(list(Class = c(NA, "Total live animals 1/", NA, NA, 
NA, NA, NA, "Bovine animals, live", NA, NA, NA, NA, "Swine, live", 
NA, NA, NA, "Sheep and goats, live", NA, NA, NA), Source = c(NA, 
NA, "CANADA", "MEXICO", "REST OF WORLD", "WORLD", "Quantity", 
NA, "CANADA", "MEXICO", "WORLD", "Quantity", NA, "CANADA", "WORLD", 
"Quantity", NA, "CANADA", "WORLD", "Quantity"), `1999` = c(NA, 
NA, "876.86900000000003", "292.15800000000002", "0.14799999999991087", 
"1169.175", "6058.3639999999996", NA, "639.02099999999996", "292.12700000000001", 
"931.14700000000005", "1868.85", NA, "216.06399999999999", "216.16399999999999", 
"4136.3490000000002", NA, "5.298", "5.3289999999999997", "53.164999999999999"
), `2000` = c(NA, NA, "995.94500000000005", "405.31099999999998", 
"7.6000000000135515E-2", "1401.3320000000001", "6521.7830000000004", 
NA, "680.55499999999995", "405.291", "1085.846", "2115.8440000000001", 
NA, "290.18599999999998", "290.262", "4352.9790000000003", NA, 
"5.7270000000000003", "5.7469999999999999", "52.96"), `2001` = c(NA, 
NA, "1343.479", "407.90100000000001", "2.6999999999816282E-2", 
"1751.4069999999999", "7758.1139999999996", NA, "966.86", "407.88799999999998", 
"1374.7629999999999", "2353.1260000000002", NA, "344.267", "344.267", 
"5316.26", NA, "8.3849999999999998", "8.4009999999999998", "88.727999999999994"
), `2002` = c(NA, NA, "1394.8150000000001", "300.49599999999998", 
"0.39899999999988722", "1695.71", "8302.9", NA, "1056.4960000000001", 
"300.49599999999998", "1357.0070000000001", "2426.1660000000002", 
NA, "299.505", "299.70100000000002", "5725.6980000000003", NA, 
"12.375999999999999", "12.564", "151.036"), `2003` = c(NA, NA, 
"784.26499999999999", "469.92599999999999", "0.17700000000002092", 
"1254.3679999999999", "9223.2039999999997", NA, "361.27199999999999", 
"469.92599999999999", "831.19899999999996", "1718.5650000000001", 
NA, "389.28", "389.30700000000002", "7429.4080000000004", NA, 
"7.5350000000000001", "7.6840000000000002", "75.230999999999995"
), `2004` = c(NA, NA, "560.14099999999996", "540.99699999999996", 
"0.52899999999999636", "1101.6669999999999", "9866.2780000000002", 
NA, "5.5E-2", "540.97900000000004", "541.03300000000002", "1366.1659999999999", 
NA, "529.35199999999998", "529.86", "8499.9449999999997", NA, 
"0", "0.03", "0.16700000000000001"), `2005` = c(NA, NA, "1134.8900000000001", 
"515.452", "0.29599999999982174", "1650.6379999999999", "9951.94", 
NA, "526.17200000000003", "515.41099999999994", "1041.5830000000001", 
"1818.3969999999999", NA, "580.78899999999999", "580.82899999999995", 
"8131.1589999999997", NA, "7.5999999999999998E-2", "0.20799999999999999", 
"2.3839999999999999"), `2006` = c(NA, NA, "1616.479", "524.24900000000002", 
"0.31999999999970896", "2141.0479999999998", "10985.52", NA, 
"1032.4000000000001", "524.23800000000006", "1556.636", "2301.8040000000001", 
NA, "558.91", "558.91", "8680.5859999999993", NA, "0.40300000000000002", 
"0.41499999999999998", "3.13"), `2007` = c("Million $", NA, "2069.1579999999999", 
"475.42", "0.11099999999987631", "2544.6889999999999", "12419.455", 
NA, "1411.558", "475.42", "1886.9780000000001", "2508.6689999999999", 
NA, "630.00900000000001", "630.02599999999995", "9910.6610000000001", 
NA, "2.4E-2", "6.8000000000000005E-2", "0.125"), `2008` = c(NA, 
NA, "1920.6969999999999", "298.24900000000002", "9.5000000000254659E-2", 
"2219.0410000000002", "11558.616", NA, "1427.2470000000001", 
"298.24900000000002", "1725.4970000000001", "2268.846", NA, "466.66800000000001", 
"466.66800000000001", "9289.7669999999998", NA, "8.0000000000000002E-3", 
"8.0000000000000002E-3", "3.0000000000000001E-3"), `2009` = c(NA, 
NA, "1244.5440000000001", "380.97300000000001", "9.1999999999870852E-2", 
"1625.6089999999999", "8349.9950000000008", NA, "931.88599999999997", 
"380.97300000000001", "1312.8589999999999", "2018.4580000000001", 
NA, "285.524", "285.524", "6331.5370000000003", NA, "0", "0", 
"0"), `2010` = c(NA, NA, "1444.7629999999999", "522.22799999999995", 
"0.27199999999993452", "1967.2629999999999", "7997.5940000000001", 
NA, "1068.0989999999999", "522.22799999999995", "1590.329", "2298.473", 
NA, "349.59300000000002", "349.608", "5697.6090000000004", NA, 
"7.4999999999999997E-2", "0.14099999999999999", "1.512"), `2011` = c(NA, 
NA, "1227.779", "616.80200000000002", "5.4000000000087311E-2", 
"1844.635", "7872.6840000000002", NA, "847.86699999999996", "616.80200000000002", 
"1464.6679999999999", "2115.116", NA, "347.83800000000002", "347.83800000000002", 
"5748.56", NA, "1.181", "1.181", "9.0079999999999991"), `2012` = c(NA, 
NA, "1432.0730000000001", "716.904", "0.10400000000004184", "2149.0810000000001", 
"7909.7569999999996", NA, "1073.6510000000001", "716.904", "1790.5550000000001", 
"2291.1790000000001", NA, "316.58999999999997", "316.58999999999997", 
"5615.6930000000002", NA, "0.28399999999999997", "0.28399999999999997", 
"2.8849999999999998"), `2013` = c(NA, NA, "1640.125", "508.33600000000001", 
"2.4999999999863576E-2", "2148.4859999999999", "6947.2889999999998", 
NA, "1282.3920000000001", "508.33600000000001", "1790.7260000000001", 
"2039.7719999999999", NA, "319.83699999999999", "319.83699999999999", 
"4904.0569999999998", NA, "0.34699999999999998", "0.34699999999999998", 
"3.46"), `2014` = c(NA, NA, "2207.404", "738.54499999999996", 
"1.6000000000076398E-2", "2945.9650000000001", "7232.5640000000003", 
NA, "1754.615", "738.54499999999996", "2493.1590000000001", "2355.2040000000002", 
NA, "410.31599999999997", "410.33300000000003", "4873.2960000000003", 
NA, "0.39900000000000002", "0.39900000000000002", "4.0640000000000001"
), `2015` = c(NA, NA, 1711.844, 881.67, 0.0969999999997526, 2593.611, 
7661.203, NA, 1340.707, 881.67, 2222.376, 1996.221, NA, 333.077, 
333.077, 5656.871, NA, 0.563, 0.578, 8.111), `2016` = c(NA, NA, 
1406.048, 584.568, 0.118999999999915, 1990.735, 7335.19, NA, 
1062.578, 584.568, 1647.147, 1715.476, NA, 295.494, 295.511, 
5598.491, NA, 1.638, 1.638, 21.223), `2017` = c(NA, NA, 1228.098, 
714.667, 0.112999999999829, 1942.878, 7365.575, NA, 859.42, 714.667, 
1574.087, 1815.707, NA, 325.954, 325.994, 5540.777, NA, 0.497, 
0.524, 9.091)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame"))
2 Answers

We may use lapply instead of sapply as sapply returns a matrix and this can have only a single class i.e. if there is any column that is a character, it can result in character

animals[3:18] <- lapply(animals[3:18], as.numeric)

Or more easily

animals <- type.convert(animals, as.is = TRUE)

Or with dplyr, use across to loop over the columns

library(dplyr)
animals <- animals %>%
     mutate(across(3:18, as.numeric))

Or dynamically

animals <- animals %>% 
   mutate(across(c(where(is.character), -matches("^\\D+")), as.numeric))

-output

> str(animals)
tibble [20 × 21] (S3: tbl_df/tbl/data.frame)
 $ Class : chr [1:20] NA "Total live animals 1/" NA NA ...
 $ Source: chr [1:20] NA NA "CANADA" "MEXICO" ...
 $ 1999  : num [1:20] NA NA 876.869 292.158 0.148 ...
 $ 2000  : num [1:20] NA NA 995.945 405.311 0.076 ...
 $ 2001  : num [1:20] NA NA 1343.479 407.901 0.027 ...
 $ 2002  : num [1:20] NA NA 1394.815 300.496 0.399 ...
 $ 2003  : num [1:20] NA NA 784.265 469.926 0.177 ...
 $ 2004  : num [1:20] NA NA 560.141 540.997 0.529 ...
 $ 2005  : num [1:20] NA NA 1134.89 515.452 0.296 ...
 $ 2006  : num [1:20] NA NA 1616.48 524.25 0.32 ...
 $ 2007  : num [1:20] NA NA 2069.158 475.42 0.111 ...
 $ 2008  : num [1:20] NA NA 1920.697 298.249 0.095 ...
 $ 2009  : num [1:20] NA NA 1244.544 380.973 0.092 ...
 $ 2010  : num [1:20] NA NA 1444.763 522.228 0.272 ...
 $ 2011  : num [1:20] NA NA 1227.779 616.802 0.054 ...
 $ 2012  : num [1:20] NA NA 1432.073 716.904 0.104 ...
 $ 2013  : num [1:20] NA NA 1640.125 508.336 0.025 ...
 $ 2014  : num [1:20] NA NA 2207.404 738.545 0.016 ...
 $ 2015  : num [1:20] NA NA 1711.844 881.67 0.097 ...
 $ 2016  : num [1:20] NA NA 1406.048 584.568 0.119 ...
 $ 2017  : num [1:20] NA NA 1228.098 714.667 0.113 ...

Try to combine with format function.

For instance,

as.numeric("12389054328902")
"1.238905e+13"
format(as.numeric("12389054328902"), scientific = F)
"12389054328902"
Related