在 R 中有没有办法根据列名和值创建新列?欢迎整洁的解决方案

In R is there a way to create a new column based on column names and values? Tidy solution welcome

具体来说,我有一个杂乱无章的 data.frame,亚种品种在单独的列中,像这样;

# Data
Genus<- c("Metrosideros", "Gahnia", "Acacia")
Species<- c("polymorpha", "aspera", "koa")
Subspecies<- c("", "globosa","")
Variety<- c("glaberrima", "", "")
df<-data.frame(Genus, Species, Subspecies, Variety)

但我想要一个看起来像这样的新专栏;

df$Sciname<- c("Metrosideros polymorpha var. glaberrima",
               "Gahnia aspera subsp. globosa",
               "Acacia koa")

使用 paste()ifelse() 可能有一个聪明的解决方案,但我想不出来。如果有欢迎的 tidyverse (dplyr) 解决方案。感谢您的帮助!

您可以通过 paste() 和一点索引来实现。

with(df, paste(
  Genus,
  Species,
  c("", "subsp.")[(Subspecies != "") + 1],
  Subspecies,
  c("", "var.")[(Variety != "") + 1],
  Variety
))

[1] "Metrosideros polymorpha   var. glaberrima" "Gahnia aspera subsp. globosa   "           "Acacia koa    "

您可以在结果中使用 stringr::str_squish() 来去除不需要的空格,这样会得到:

[1] "Metrosideros polymorpha var. glaberrima" "Gahnia aspera subsp. globosa"            "Acacia koa"  

这里有另一个选项 tidyverse,我们可以在 SubspeciesVariety 列中添加额外的字符串,然后我们可以使用 unite 组合所有列.然后,我们可以清理 Sciname 列,然后重新加入原始数据框。

library(tidyverse)

df %>%
  mutate(Subspecies = ifelse(Subspecies != "", paste0("subsp. ", Subspecies), Subspecies),
         Variety = ifelse(Variety != "", paste0("var. ", Variety), Variety)) %>%
  unite("Sciname", Genus:Variety, sep = " ", remove = FALSE, na.rm = T) %>%
  select(Sciname) %>%
  mutate(Sciname = trimws(Sciname)) %>%
  bind_cols(df, .)

输出

         Genus    Species Subspecies    Variety                                  Sciname
1 Metrosideros polymorpha            glaberrima Metrosideros polymorpha  var. glaberrima
2       Gahnia     aspera    globosa                        Gahnia aspera subsp. globosa
3       Acacia        koa                                                     Acacia koa