dhbrand
dhbrand

Reputation: 162

str_split on first and second occurence of delimter at different locations in character vector

I have a character list that has weather variables followed by "mean_#" where # is a number between 5 and 10. I want to subset the list to only have the weather variable names themselves. The mean weather variables look like this:

> mean_vars
 [1] "dew_mean_10"        "dew_mean_5"         "dew_mean_6"         "dew_mean_7"        
 [5] "dew_mean_8"         "dew_mean_9"         "humid_mean_10"      "humid_mean_5"      
 [9] "humid_mean_6"       "humid_mean_7"       "humid_mean_8"       "humid_mean_9"      
[13] "rain_mean_10"       "rain_mean_5"        "rain_mean_6"        "rain_mean_7"       
[17] "rain_mean_8"        "rain_mean_9"        "soil_moist_mean_10" "soil_moist_mean_5" 
[21] "soil_moist_mean_6"  "soil_moist_mean_7"  "soil_moist_mean_8"  "soil_moist_mean_9" 
[25] "soil_temp_mean_10"  "soil_temp_mean_5"   "soil_temp_mean_6"   "soil_temp_mean_7"  
[29] "soil_temp_mean_8"   "soil_temp_mean_9"   "solar_mean_10"      "solar_mean_5"      
[33] "solar_mean_6"       "solar_mean_7"       "solar_mean_8"       "solar_mean_9"      
[37] "temp_mean_10"       "temp_mean_5"        "temp_mean_6"        "temp_mean_7"       
[41] "temp_mean_8"        "temp_mean_9"        "wind_dir_mean_10"   "wind_dir_mean_5"   
[45] "wind_dir_mean_6"    "wind_dir_mean_7"    "wind_dir_mean_8"    "wind_dir_mean_9"   
[49] "wind_gust_mean_10"  "wind_gust_mean_5"   "wind_gust_mean_6"   "wind_gust_mean_7"  
[53] "wind_gust_mean_8"   "wind_gust_mean_9"   "wind_spd_mean_10"   "wind_spd_mean_5"   
[57] "wind_spd_mean_6"    "wind_spd_mean_7"    "wind_spd_mean_8"    "wind_spd_mean_9"

And this is all I want at the end:

> var_names                                                                                           
       "dew"      "humid"       "rain"      "solar"       "temp" "soil_moist"  "soil_temp"    "wind_dir"  "wind_gust"   "wind_spd" 

Now I figured out how to do it but I fill my method is extraneous due to a lack of ability with regular expressions. I also will have to repeat my process 20 times substituting "mean" with other words.

var_names <- unique(str_split_fixed(mean_vars, "_", n = 3)[c(1:18,31:42),1])
var_names <- unlist(c(var_names, unique(unite(as_tibble(str_split_fixed(mean_vars, "_", n = 3)[c(19:30,43:60), 1:2])))))

I've been trying to stay within the realm of the tidyverse packages as much as possible so I was using stringr::str_split_fixed.

If you have a solution using this same function that would be ideal as I could continue the same programming style, but I'm open to all suggestions.

Thanks.

Upvotes: 0

Views: 47

Answers (1)

G. Grothendieck
G. Grothendieck

Reputation: 269526

Use sub and unique. This is shorter and has no package dependencies (or use unique(str_replace(mean_vars, "_mean.*", "")) with stringr):

unique(sub("_mean.*", "", mean_vars))

giving:

 [1] "dew"        "humid"      "rain"       "soil_moist" "soil_temp" 
 [6] "solar"      "temp"       "wind_dir"   "wind_gust"  "wind_spd"  

If for some reason you really want to use str_split then:

rmMean <- function(x) paste(head(x, -2), collapse = "_")
unique(sapply(str_split(mean_vars, "_"), rmMean))

Note

mean_vars <- c("dew_mean_10", "dew_mean_5", "dew_mean_6", "dew_mean_7", "dew_mean_8", 
"dew_mean_9", "humid_mean_10", "humid_mean_5", "humid_mean_6", 
"humid_mean_7", "humid_mean_8", "humid_mean_9", "rain_mean_10", 
"rain_mean_5", "rain_mean_6", "rain_mean_7", "rain_mean_8", "rain_mean_9", 
"soil_moist_mean_10", "soil_moist_mean_5", "soil_moist_mean_6", 
"soil_moist_mean_7", "soil_moist_mean_8", "soil_moist_mean_9", 
"soil_temp_mean_10", "soil_temp_mean_5", "soil_temp_mean_6", 
"soil_temp_mean_7", "soil_temp_mean_8", "soil_temp_mean_9", "solar_mean_10", 
"solar_mean_5", "solar_mean_6", "solar_mean_7", "solar_mean_8", 
"solar_mean_9", "temp_mean_10", "temp_mean_5", "temp_mean_6", 
"temp_mean_7", "temp_mean_8", "temp_mean_9", "wind_dir_mean_10", 
"wind_dir_mean_5", "wind_dir_mean_6", "wind_dir_mean_7", "wind_dir_mean_8", 
"wind_dir_mean_9", "wind_gust_mean_10", "wind_gust_mean_5", "wind_gust_mean_6", 
"wind_gust_mean_7", "wind_gust_mean_8", "wind_gust_mean_9", "wind_spd_mean_10", 
"wind_spd_mean_5", "wind_spd_mean_6", "wind_spd_mean_7", "wind_spd_mean_8", 
"wind_spd_mean_9")

Upvotes: 1

Related Questions