重命名因子水平取决于两个其他因素的独特组合

时间:2017-06-12 16:09:06

标签: r

假设我有一个像这样的数据框:

df<- 
 plantfam        lepfam                      lepsp
 Asteraceae      Geometridae                 Eois sp         
 Asteraceae      Erebidae                                     
 Poaceae         Erebidae                    
 Poaceae         Noctuidae                         
 Asteraceae      Saturnidae                  Polyphemous sp        
 Melastomaceae   Noctuidae                   
 Asteraceae             
 Melastomaceae   
                 Noctuidae
                 Erebidae

我希望以lepspplantfam的独特组合为条件制作唯一的lepfam个名称。输出如下所示:

output<- 
 plantfam        lepfam                      lepsp
 Asteraceae      Geometridae                 Eois sp         
 Asteraceae      Erebidae                    Erebidae_morphosp1                 
 Poaceae         Erebidae                    Erebidae_morphosp2
 Poaceae         Noctuidae                   Noctuidae_morphosp1      
 Asteraceae      Saturnidae                  Polyphemous sp        
 Melastomaceae   Noctuidae                   Noctuidae_morphosp2
 Asteraceae             
 Melastomaceae   
                 Noctuidae
                 Erebidae

注意:每个lepfam必须首先进行子集化。对于plantfam子集中的每个唯一lepfam lepfam组合,都会指定一个形态物种名称。对于plantfamlepfam为空白的那些,一个形态物种没有指定。

我引用了以下内容: https://stackoverflow.com/a/44479195/8061255 R: For loop- For each subset, add character values that incorporate the subsetted factor level and unique iD numbers

我尝试了以下代码但没有成功:

file<-file %>%
group_by(lepfam) %>% 
mutate(lepsp=ifelse(lepsp!=""| plantfam=="" & lepfam=="", lepsp, 
                  paste0(lepfam, "_morphosp", match(lepfam, unique 
  (lepfam)))))

1 个答案:

答案 0 :(得分:0)

当我想回答时,你已经自己完成了。无论如何,我会这样做,因为我不确定你的解决方案是否正确(或者我误解了这个问题)。

因此,您的两个解决方案都会生成一个输出,这与作为示例给出的输出不同。

df <- read.table(sep = ",", header = TRUE, stringsAsFactors = FALSE, text = "
plantfam,lepfam,lepsp\n
Asteraceae,Geometridae,Eois sp\n
Asteraceae,Erebidae,\n
Poaceae,Erebidae,\n
Poaceae,Noctuidae,\n
Asteraceae,Saturnidae,Polyphemous sp\n
Melastomaceae,Noctuidae,\n
Asteraceae,,\n
Melastomaceae,,\n
,Noctuidae,\n
,Erebidae,\n
")

df %>% group_by(lepfam) %>% mutate(lepsp=ifelse(lepsp!="" | plantfam=="" & lepfam=="", lepsp, paste0(lepfam, "_morphosp", match(lepfam, unique(lepfam)))))
Source: local data frame [10 x 3]
Groups: lepfam [5]

# A tibble: 10 x 3
        plantfam      lepfam               lepsp
           <chr>       <chr>               <chr>
 1    Asteraceae Geometridae             Eois sp
 2    Asteraceae    Erebidae  Erebidae_morphosp1
 3       Poaceae    Erebidae  Erebidae_morphosp1
 4       Poaceae   Noctuidae Noctuidae_morphosp1
 5    Asteraceae  Saturnidae      Polyphemous sp
 6 Melastomaceae   Noctuidae Noctuidae_morphosp1
 7    Asteraceae                      _morphosp1
 8 Melastomaceae                      _morphosp1
 9                 Noctuidae Noctuidae_morphosp1
10                 Erebidae   Erebidae_morphosp1

df %>% group_by(lepfam) %>% mutate(lepsp=ifelse(lepsp!="" | plantfam=="" | lepfam=="", lepsp, paste0(lepfam, "_morphosp", match(lepfam, unique (lepfam)))))
Source: local data frame [10 x 3]
Groups: lepfam [5]

# A tibble: 10 x 3
        plantfam      lepfam               lepsp
           <chr>       <chr>               <chr>
 1    Asteraceae Geometridae             Eois sp
 2    Asteraceae    Erebidae  Erebidae_morphosp1
 3       Poaceae    Erebidae  Erebidae_morphosp1
 4       Poaceae   Noctuidae Noctuidae_morphosp1
 5    Asteraceae  Saturnidae      Polyphemous sp
 6 Melastomaceae   Noctuidae Noctuidae_morphosp1
 7    Asteraceae                                
 8 Melastomaceae                                
 9                 Noctuidae                    
10                  Erebidae                    

显然,第一种解决方案是错误的。第二个似乎也是错误的,因为名称不是唯一的:Erebidae_morphosp1Erebidae_morphosp1包括两次。

这是我的解决方案。它非常难看,远非优雅,但输出与示例中的输出相匹配。

condition <- quote(lepsp == "" & plantfam != "" & lepfam != "")
subset1 <- df %>% filter(condition) %>% group_by(lepfam) %>% mutate(lepsp = paste0(lepfam,"_morphosp",row_number()))
subset2 <- df %>% filter(condition) %>% setdiff(df, .)
union(subset1, subset2) %>% arrange(lepsp)
Source: local data frame [10 x 3]
Groups: lepfam [5]

# A tibble: 10 x 3
        plantfam      lepfam               lepsp
           <chr>       <chr>               <chr>
 1                  Erebidae                    
 2    Asteraceae                                
 3 Melastomaceae                                
 4                 Noctuidae                    
 5    Asteraceae Geometridae             Eois sp
 6    Asteraceae    Erebidae  Erebidae_morphosp1
 7       Poaceae    Erebidae  Erebidae_morphosp2
 8       Poaceae   Noctuidae Noctuidae_morphosp1
 9 Melastomaceae   Noctuidae Noctuidae_morphosp2
10    Asteraceae  Saturnidae      Polyphemous sp

我稍后会以新的心态思考它,并且可能会添加更优雅和更短的东西。