我有一个数据框,其中一部分如下所示:
Domain <- c(rep("Bacteria",3),rep("Archaea", 2))
Phylum <- c("Proteobacteria","Cyanobacteria","Planctomycetota", "Thermoplasmatota", "Thermoplasmatota")
Class <- c("Alphaproteobacteria","Cyanobacteriia","Phycisphaerae","Poseidoniia_A",NA)
Order <- c("Sphingomonadales", NA, "Phycisphaerales", "Poseidoniales", NA)
Family <- c("Emcibacteraceae", NA, NA, "Poseidonia", NA)
Genus <- c("UBA4441", NA,NA,NA,NA)
Species <- c("UBA4441 sp", NA,NA,NA,NA)
demo_table <- data.frame(Domain, Phylum, Class, Order, Family, Genus, Species)
Run Code Online (Sandbox Code Playgroud)
这里的要点是我想创建一个名为“赋值”的新列,该列包含逐行包含非 NA 值的最后两列的合并,并且这些值由空格分隔。
这是预期的输出:
| 领域 | 门 | 班级 | 命令 | 家庭 | 属 | 物种 | 分配 |
|---|---|---|---|---|---|---|---|
| 细菌 | 变形菌门 | α变形菌门 | 鞘氨醇单胞菌目 | 杆菌科 | UBA4441 | UBA4441 sp | UBA4441 UBA4441 sp |
| 细菌 | 蓝细菌 | 蓝细菌 | 不适用 | 不适用 | 不适用 | 不适用 | 蓝藻 蓝藻 |
| 细菌 | 浮霉菌门 | 球球族 | 球球目 | 不适用 | 不适用 | 不适用 | 球球目 |
| 古细菌 | 热原体门 | 波塞冬尼亚_A | 海神目 | 波塞多尼亚 | 不适用 | 不适用 | 波塞冬目 |
| 古细菌 | 热原体门 | 不适用 | 不适用 | 不适用 | 不适用 | 不适用 | 热原体古细菌 |
我认为这paste()可能适用于这种情况,但不确定如何实现它,以便我可以获得上述预期的输出数据帧。
我们可以使用base R- 循环遍历行,用 删除 NA ,用和na.omit获取最后两个元素tailn = 2paste
demo_table$assignation <- apply(demo_table, 1,
function(x) paste(tail(na.omit(x), 2), collapse = " "))
Run Code Online (Sandbox Code Playgroud)
-输出
demo_table$assignation
[1] "UBA4441 UBA4441 sp" "Cyanobacteria Cyanobacteriia" "Phycisphaerae Phycisphaerales" "Poseidoniales Poseidonia"
[5] "Archaea Thermoplasmatota"
Run Code Online (Sandbox Code Playgroud)
with tidyverse,我们也可以使用unite并删除 NAwith na.rm = TRUE,然后提取最后两个单词
library(dplyr)
library(tidyr)
library(stringr)
demo_table %>%
unite(assignation, everything(), na.rm = TRUE, remove = FALSE) %>%
mutate(assignation = str_replace(assignation,
".*_([^_]+)_([^_]+)$", "\\1 \\2")) %>%
relocate(assignation, .after =last_col())
Run Code Online (Sandbox Code Playgroud)