3

I simply want to coerce as numbers --i.e., to apply as.numeric to--any columns which have a 1 as their first entry (i.e., a character). So I would expect to turn:

tibble(a = c("1", "2"), b = c("Fred", "Kevin"), c = 1:2)

into

tibble(a = 1:2, b = c("Fred", "Kevin"), c = 1:2)
user438383
  • 5,716
  • 8
  • 28
  • 43
James Bejon
  • 189
  • 5

4 Answers4

3

You could use dplyr:

library(dplyr)

data %>% 
  mutate(across(where(~ first(.x) == "1" & !is.na(first(.x))), as.numeric)).

returns

# A tibble: 2 x 5
      a b         c     d e    
  <dbl> <chr> <dbl> <dbl> <lgl>
1     1 Fred      1     1 NA    
2     2 Kevin     2     3 NA   

Data

data <- tibble(a = c("1", "2"), 
               b = c("Fred", "Kevin"), 
               c = 1:2, 
               d = c("1", "3"), 
               e = c(NA, NA))
Martin Gal
  • 16,640
  • 5
  • 21
  • 39
  • Thanks for the reply. One snag--which I have in fact realised was my problem in the first place: when some of the values are NA, it errors. For instance, set the last column to e = c(NA, NA), and an error arises. Any ideas on how to fix it? Many thanks for the reply! James. – James Bejon Jul 04 '21 at 17:40
  • You could try `mutate(across(where(~ first(.x) == "1" & !is.na(first(.x))), as.numeric))`. – Martin Gal Jul 04 '21 at 17:43
  • 1
    Thanks Martin. That's done the job. Appreciate the help. James. – James Bejon Jul 04 '21 at 18:46
1

It's not doing strictly whate you asked for, but you could use readr's guess_parser or parse_guess functions. See https://readr.tidyverse.org/reference/parse_guess.html for more details.

In your case you could do:

df %>% mutate(across(everything(),parse_guess))

Which would parse all columns. Or for just parsing if the column is going to numeric:

parse_guess_numeric <- function (x){
    if (guess_parser(x, guess_integer=FALSE)=="double"){
        as.numeric(x)
    } else {
        x
    }

}

df %>% mutate(across(everything(),parse_guess_numeric))
s_pike
  • 1,710
  • 1
  • 10
  • 22
1

There are many ways to approach this: use type.convert or type_convert from readr:

type.convert(df, as.is = TRUE)
# A tibble: 2 x 3
      a b         c
  <int> <chr> <int>
1     1 Fred      1
2     2 Kevin     2


readr::type_convert(df)

-- Column specification ---------------------------------------------------------------------
cols(
  a = col_double(),
  b = col_character()
)

# A tibble: 2 x 3
      a b         c
  <dbl> <chr> <int>
1     1 Fred      1
2     2 Kevin     2
Onyambu
  • 67,392
  • 3
  • 24
  • 53
0
library(tidyverse)
df <- tibble(a = c("1", "2"), b = c("Fred", "Kevin"), c = 1:2, d = c(NA, NA))
fltr <- names(df)[map_chr(df, guess_parser) == "double"]
mutate(df, across(all_of(fltr), as.numeric))
#> # A tibble: 2 x 4
#>       a b         c d    
#>   <dbl> <chr> <dbl> <lgl>
#> 1     1 Fred      1 NA   
#> 2     2 Kevin     2 NA

Created on 2021-07-04 by the reprex package (v2.0.0)

Yuriy Saraykin
  • 8,390
  • 1
  • 7
  • 14