Rename levels of factor by filtering, grouping then conditional on statement

Viewed 178

I have a dataframe like so:

 data<- data.frame(ID= seq(1,12, 1), 
                   plantfam= c(1,1,2,2,1,1,1,1,2,2,3,3), 
                   lepsp= c(rep("A", 4), "B", "B", rep("C", 6)), 
                   needsmorpho= c(rep("yes", 4),"no", "no", rep("yes", 6)))

I need to first filter all needsmorpho that are yes. Then I need to group all lepsp with the same plantfam. For each unique lepsp and plantfam match the lepsp will be given a unique morpho species name. To make a morphosp name I would like to paste morphosp and a unique number based on the unique lepsp and plantfam matches. The output would be:

output<- data.frame(ID= seq(1,12, 1), 
                   plantfam= c(1,1,2,2,1,1,1,1,2,2,3,3), 
                   lepsp= c("A_morpho1","A_morpho1","A_morpho2","A_morpho2",
                         "B","B","C_morpho1","C_morpho1",
                         "C_morpho2","C_morpho2","C_morpho3","C_morpho3"), 
                   needsmorpho= c(rep("yes", 4),"no", "no", rep("yes", 6)))

I have tried:

subset1 <- 
 file %>% 
 filter(NeedsMorpho == "yes") %>% 
 group_by(lepsp) %>%  
 mutate(lepsp = 
 paste0(lepsp,"_morphosp",match(plantfam,unique(plantfam))))

subset2 <- 
file %>% 
filter(NeedsMorpho == "yes") %>% 
setdiff(file, .)

file<-union(subset1, subset2) %>% arrange(lepsp)
2 Answers

Does this achieve what you're after?

library( data.table )
setDT(data)
data[ needsmorpho == "yes", lepsp := paste0(lepsp,"_morphosp",plantfam) ]

With case_when from dplyr you could do the following:

library(tidyverse)

data %>% 
  mutate(lepsp = case_when(needsmorpho == "yes" ~ paste0(lepsp, "_morpho", plantfam),
                           TRUE ~ as.character(lepsp)))

Which returns:

   ID plantfam     lepsp needsmorpho
1   1        1 A_morpho1         yes
2   2        1 A_morpho1         yes
3   3        2 A_morpho2         yes
4   4        2 A_morpho2         yes
5   5        1         B          no
6   6        1         B          no
7   7        1 C_morpho1         yes
8   8        1 C_morpho1         yes
9   9        2 C_morpho2         yes
10 10        2 C_morpho2         yes
11 11        3 C_morpho3         yes
12 12        3 C_morpho3         yes
Related