在 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
,我们可以在 Subspecies
和 Variety
列中添加额外的字符串,然后我们可以使用 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
具体来说,我有一个杂乱无章的 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
,我们可以在 Subspecies
和 Variety
列中添加额外的字符串,然后我们可以使用 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