Changing Class and Mode from Character to Numeric
The lines
as.factor(df$StudyAreaVisitNote)
as.numeric(df$Year)
as.numeric(df$Session)
do not permanently change the values in df
. They return transformed vectors that are printed to the console, then, because you do not save them anywhere, they disappear as soon as that line in done being called. Generally objects in R are not updated via referece, you must alwayts re-assign the returned result to wherevver you would like to store it. So try
df$Year <- as.numeric(df$Year)
df$Session <- as.numeric(df$Session)
instead
Change the class from factor to numeric of many columns in a data frame
Further to Ramnath's answer, the behaviour you are experiencing is that due to as.numeric(x)
returning the internal, numeric representation of the factor x
at the R level. If you want to preserve the numbers that are the levels of the factor (rather than their internal representation), you need to convert to character via as.character()
first as per Ramnath's example.
Your for
loop is just as reasonable as an apply
call and might be slightly more readable as to what the intention of the code is. Just change this line:
stats[,i] <- as.numeric(stats[,i])
to read
stats[,i] <- as.numeric(as.character(stats[,i]))
This is FAQ 7.10 in the R FAQ.
HTH
Convert a column of character mode into numeric in R?
x <- "24,31"
y <- as.numeric(gsub(",", ".", x))
y
# [1] 24.31
class(y)
# [1] "numeric"
A side note
I think depending on the data file you have, you might even want to prevent this to happen in the first place defining dec. Be careful if your sep is a comma as well though. It still can be an option, so you do not get your values as a character and therefor no need to do any replacements.
fread(file, header = T, sep = ";", dec = ",") # fread is data.table, but I think read.csv and any others support it as well
How to convert a data frame column to numeric type?
Since (still) nobody got check-mark, I assume that you have some practical issue in mind, mostly because you haven't specified what type of vector you want to convert to numeric
. I suggest that you should apply transform
function in order to complete your task.
Now I'm about to demonstrate certain "conversion anomaly":
# create dummy data.frame
d <- data.frame(char = letters[1:5],
fake_char = as.character(1:5),
fac = factor(1:5),
char_fac = factor(letters[1:5]),
num = 1:5, stringsAsFactors = FALSE)
Let us have a glance at data.frame
> d
char fake_char fac char_fac num
1 a 1 1 a 1
2 b 2 2 b 2
3 c 3 3 c 3
4 d 4 4 d 4
5 e 5 5 e 5
and let us run:
> sapply(d, mode)
char fake_char fac char_fac num
"character" "character" "numeric" "numeric" "numeric"
> sapply(d, class)
char fake_char fac char_fac num
"character" "character" "factor" "factor" "integer"
Now you probably ask yourself "Where's an anomaly?" Well, I've bumped into quite peculiar things in R, and this is not the most confounding thing, but it can confuse you, especially if you read this before rolling into bed.
Here goes: first two columns are character
. I've deliberately called 2nd one fake_char
. Spot the similarity of this character
variable with one that Dirk created in his reply. It's actually a numerical
vector converted to character
. 3rd and 4th column are factor
, and the last one is "purely" numeric
.
If you utilize transform
function, you can convert the fake_char
into numeric
, but not the char
variable itself.
> transform(d, char = as.numeric(char))
char fake_char fac char_fac num
1 NA 1 1 a 1
2 NA 2 2 b 2
3 NA 3 3 c 3
4 NA 4 4 d 4
5 NA 5 5 e 5
Warning message:
In eval(expr, envir, enclos) : NAs introduced by coercion
but if you do same thing on fake_char
and char_fac
, you'll be lucky, and get away with no NA's:
> transform(d, fake_char = as.numeric(fake_char),
char_fac = as.numeric(char_fac))
char fake_char fac char_fac num
1 a 1 1 1 1
2 b 2 2 2 2
3 c 3 3 3 3
4 d 4 4 4 4
5 e 5 5 5 5
If you save transformed data.frame
and check for mode
and class
, you'll get:
> D <- transform(d, fake_char = as.numeric(fake_char),
char_fac = as.numeric(char_fac))
> sapply(D, mode)
char fake_char fac char_fac num
"character" "numeric" "numeric" "numeric" "numeric"
> sapply(D, class)
char fake_char fac char_fac num
"character" "numeric" "factor" "numeric" "integer"
So, the conclusion is: Yes, you can convert character
vector into a numeric
one, but only if it's elements are "convertible" to numeric
. If there's just one character
element in vector, you'll get error when trying to convert that vector to numerical
one.
And just to prove my point:
> err <- c(1, "b", 3, 4, "e")
> mode(err)
[1] "character"
> class(err)
[1] "character"
> char <- as.numeric(err)
Warning message:
NAs introduced by coercion
> char
[1] 1 NA 3 4 NA
And now, just for fun (or practice), try to guess the output of these commands:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Kind regards to Patrick Burns! =)
Converting Character to Numeric without NA Coercion in R
As Anando pointed out, the problem is somewhere in your data, and we can't really help you much without a reproducible example. That said, here's a code snippet to help you pin down the records in your data that are causing you problems:
test = as.character(c(1,2,3,4,'M'))
v = as.numeric(test) # NAs intorduced by coercion
ix.na = is.na(v)
which(ix.na) # row index of our problem = 5
test[ix.na] # shows the problematic record, "M"
Instead of guessing as to why NAs are being introduced, pull out the records that are causing the problem and address them directly/individually until the NAs go away.
UPDATE: Looks like the problem is in your call to str_replace_all
. I don't know the stringr
library, but I think you can accomplish the same thing with gsub
like this:
v2 = c("1.00","2.00","3.00")
gsub("\\.00", "", v2)
[1] "1" "2" "3"
I'm not entirely sure what this accomplishes though:
sum(as.numeric(v2)!=as.numeric(gsub("\\.00", "", v2))) # Illustrate that vectors are equivalent.
[1] 0
Unless this achieves some specific purpose for you, I'd suggest dropping this step from your preprocessing entirely, as it doesn't appear necessary and seems to be giving you problems.
Changing class from 'character' to other type which supports rowSums in r
You could change the storage mode of your matrix:
mmat <- matrix(c("2","3","7","0"), ncol = 2)
storage.mode(mmat) <- "double" # changed from "numeric"
rowSums(mmat)
# [1] 9 3
Converting from character to numeric in a matrix
Answered by @Sophia.
Her solution:
How about converting your matrix to data.frame before you add the character columns?
Related Topics
How to Measure Area Between 2 Distribution Curves in R/Ggplot2
How to Extract Multiples of a Number from a Vector
2 Knitr/R Markdown/Rstudio Issues: Highcharts and Morris.Js
Fixing Variance Values in Lme4
Create and Call Linear Models from List
How to Import Only One Function from Another Package, Without Loading the Entire Namespace
How to Adjust the Font Size of Tablegrob
R - Scaling Numeric Values Only in a Dataframe with Mixed Types
Extract Columns from Data Table by Numeric Indices Stored in a Vector
How to Write Special Characters in Rmarkdown Latex Documents
Difference Between [] and $ Operators for Subsetting
R - Delete Consecutive (Only) Duplicates
Rename Columns Using 'Starts_With()' Where New Prefix Is a String
Error in Terms.Formula(Formula):'.' in Formula and No 'Data' Argument