exclude part of a character string in a column in a dataframe

Viewed 63

I have a df that has several ids separated with an underscore, like so:

df1:
id           v1
1001          2 
10002_10002  19

I want the underscore removed and anything after the underscore, like so:

df1:
id           v1
1001          2 
10002        19

I tried this code, but it's giving me a list, not a df. Can someone please help?

df2 <- strsplit(df1$id, split='_', fixed=TRUE)
4 Answers

You need to access the contents of the list, and then retain the first of two elements resulting from the split:

df1$id <- strsplit(df1$id, "_", fixed=TRUE)[[1]][1]

You could also use sub here:

df1$id <- sub("_.*$", "", df1$id)

I like to use the stringr package

require(stringr)
    df1 <- data.frame(id = c("1001","1002_10002"), v1 = c(2,19))
    
    df1$id <- str_remove(df1$id, pattern = "_.+")

Here a solution with the tidyverse/stringr:

library(tidyverse)
my_df <- data.frame(
  stringsAsFactors = FALSE,
                id = c("1001", "10002_10002"),
                v1 = c(2L, 19L)
)
my_df %>% 
  mutate(id=str_remove(id, regex("(_.*)")))
#>      id v1
#> 1  1001  2
#> 2 10002 19

Created on 2020-12-03 by the reprex package (v0.3.0)

We can use word from stringr

library(stringr)
library(dplyr)
df1 %>%
     mutate(id = word(id, 1, sep="_"))
 #      id v1
 #1  1001  2
 #2 10002 19

Another option is trimws from base R

df1$id <- trimws(df1$id, whitespace = "_.*")

data

df1 <- structure(list(id = c("1001", "10002_10002"), 
v1 = c(2L, 19L)), class = "data.frame", row.names = c(NA, 
-2L))
Related