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

具体来说,我有一个不整洁的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) 解决方案。谢谢你的帮助!

回答1

您可以使用 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"

回答2

这是 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

相似文章

最新文章