Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying as.numeric only to elements of a list that can be coerced to numeric (in R)

Tags:

r

I have a function which returns a list containing individual character vectors which I would like to convert to numeric. Most of the time, all the elements of the list can easily be coerced to numeric:

and so a simplelapply(x, FUN = as.numeric) works fine.

e.g.

l <- list(a = c("1","1"), b = c("2","2"))
l
$a
[1] "1" "1"

$b
[1] "2" "2"


lapply(l, FUN = as.numeric)
$a
[1] 1 1

$b
[1] 2 2

However, in some situations, vectors contain true characters:

e.g.

l <- list(a = c("1","1"), b = c("a","b"))
l
$a
[1] "1" "1"

$b
[1] "a" "b"


lapply(l, FUN = as.numeric)
$a
[1] 1 1

$b
[1] NA NA

The solution I have come with works but feels a little convoluted:

l.id <- unlist(lapply(l, FUN = function(x){all(!is.na(suppressWarnings(as.numeric(x))))}))

l.id
 a     b 
 TRUE  FALSE 

l[l.id] <- lapply(l[l.id], FUN = as.numeric)

l
$a
[1] 1 1

$b
[1] "a" "b"

So I was just wondering if anyone out there had a more streamlined and elegant solution to suggest.

Thanks!

like image 628
Anna Krystalli Avatar asked Sep 29 '15 14:09

Anna Krystalli


1 Answers

One option would be to check whether all the elements in the vector have only numbers and if so convert to numeric or else stay as the same.

lapply(l, function(x) if(all(grepl('^[0-9.]+$', x))) as.numeric(x) else x)

Or we can use type.convert to automatically convert the class, but the character vectors will be converted to factor class.

lapply(l, type.convert)
like image 134
akrun Avatar answered Oct 20 '22 12:10

akrun