Limit string length of all cells in a dataframe?

Viewed 1561

Hi is there a way to limit the string text size for all columns in a data.frame, without having to loop through each column and using something like str_trunc one column at a time? For example the dataframe below, can I limit all text size to just 5 characters without having to do it one column at a time. If this had like 50 columns truncating one column at a time would be difficult.

g1 = data.frame ( 
  gene = c( "aaaaaaa","aaaaaaa","aaaaaaaaaaaa","a","bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
  value = c("1fdfdfdsfdsfdsfds","2fdfdfdfdsfds00","fdfdfds3","5ffffffffffff","0")
)

I tried something like this but failed. lapply(g1, str_trunc, 5)

Would be great if, with one go, I can limit any string in the dataframe to just 5 characters. so for example the first cell , row 1, column 1 would be just aaaaa

thanks.

3 Answers

In the OP's code, the str_trunc by default uses ellipsis = "...". If we change it to blank (""), it should give the same output as above. The output of lapply is a list, so we can assign it back to the data.frame or wrap with data.frame to convert the list to data.frame

library(stringr)
g1[] <- lapply(g1, str_trunc, 5, ellipsis = "")
g1
#   gene value
#1 aaaaa 1fdfd
#2 aaaaa 2fdfd
#3 aaaaa fdfdf
#4     a 5ffff
#5 bbbbb     0

Or we can use base R by converting the data.frame to matrix and use substr from base R without a loop

g1[] <- substr(as.matrix(g1), 1, 5)
g1
#   gene value
#1 aaaaa 1fdfd
#2 aaaaa 2fdfd
#3 aaaaa fdfdf
#4     a 5ffff
#5 bbbbb     0

Or using tidyverse

library(dplyr) #1.0.0
library(stringr)
g1 %>%  
      mutate(across(everything(), str_sub, 1, 5))
#   gene value
#1 aaaaa 1fdfd
#2 aaaaa 2fdfd
#3 aaaaa fdfdf
#4     a 5ffff
#5 bbbbb     0

If we have a dplyr version < 1.0.0, an option is mutate_all

g1 %>%
    mutate_all(str_sub, 1, 5)

You can use substr or substring :

g1[] <- lapply(g1, substr, 1, 5)
#OR
#g1[] <- lapply(g1, substring, 1, 5)
g1
#   gene value
#1 aaaaa 1fdfd
#2 aaaaa 2fdfd
#3 aaaaa fdfdf
#4     a 5ffff
#5 bbbbb     0

Base R anonymous function coercing factor types to characters in order to apply the substring function:

data.frame(lapply(g1, function(x){
      if(is.character(x) | is.factor(x)){
       x <- substring(x, 1, 5)
      }else{
        x
      }
    }
  )
)
Related