Craig Craig - 1 year ago 189
R Question

dplyr conditional mutate on itself

I have a data frame with a character variable consisting of mostly numeric values, with occasional known character strings as well as some

values. I want to conditionally reformat the numeric values to have one decimal place, but leave the character and
values alone.

This code works on a toy data frame and produces the desired output:

df <- data.frame(a = c("1", "2", "3", "none", NA),
stringsAsFactors = FALSE)

test <- df %>%
mutate(a = ifelse( | a == "none",
format(round(as.numeric(a), 1), nsmall = 1)))

# a
# 1 1.0
# 2 2.0
# 3 3.0
# 4 none
# 5 <NA>

But throws a warning message

Warning message:
In format(round(as.numeric(c("1", "2", "3", "none", NA)), 1), nsmall = 1) :
NAs introduced by coercion

which I believe is the case b/c
format(round(as.numeric(a), 1), nsmall = 1)))
is still acting on the entire vector, even though the values from that are only used in the
statement where the
condition is false.

I can wrap the whole thing in
, but is there some other way to have this generate the desired output without warnings within the
framework? I'm sure there's a
way to do it but this is part of a package that doesn't need
for anything else and it seems silly to make it necessary for such a small piece...

Answer Source

Use replace and you can convert just the numeric type data in column a:

test <- df %>%
               mutate(a = replace(a, ! & a != "none",
                      format(round(as.numeric(a[! & a != "none"]), 1), nsmall = 1)))

#     a
#1  1.0
#2  2.0
#3  3.0
#4 none
#5 <NA>
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download