Home > Mobile >  modify_if : apply predicate function to a dataframe
modify_if : apply predicate function to a dataframe

Time:10-11

I'm trying to apply modify_if function to a dataframe with character values:

> dataframe
  col_1   col_2   col_3
  <chr>   <chr>   <chr>                 
 1 840    1097    989            
 2 s      s       s            
 3 781    9021    9006          

I would like to insert thousands separator in character columns to get the following result:

> expected_dataframe
  col_1   col_2   col_3
  <chr>   <chr>   <chr>                 
 1 840    1 097    989            
 2 s      s        s            
 3 781    9 021    9 006          

I don't know how to call the cells in the predicate function. I tried to use nchar function but I'm facing the following error:

> modify_if(dataframe, ~ nchar(.x) >3 , ~ stri_sub( ., nchar() - 3, nchar() - 2) <- " " )
Error: Predicate functions must return a single `TRUE` or `FALSE`, not a logical vector of length 102

CodePudding user response:

modify_if allows selecting which columns to mutate, it doesn’t filter rows. In fact, you’re better off using table functions here (i.e. mutate), not ‘purrr’ verbs.

Instead, your mutation function itself must test whether each given value is longer than 3 characters. The logic of the formatting is also quite a bit more complex than simply adding a whitespace after three characters; so I’ll use the existing implementation provided by format rather than rolling my own:

add_thousands_sep = function (x) {
    num = suppressWarnings(as.numeric(x))
    result = ifelse(is.na(num), x, format(num, big.mark = ' ', scientific = FALSE))
}

mutate(dataframe, across(everything(), add_thousands_sep))

CodePudding user response:

Base R:

> as.data.frame(t(apply(dataframe, 1, function(x) sapply(x, function(y) if(!is.na(as.numeric(y))) format(as.numeric(y), big.mark=' ') else y))))
  col_1 col_2 col_3
1   840 1 097   989
2     s     s     s
3   781 9 021 9 006
  • Related