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