如何在R中基于每行最后两个非NA列创建新列assignation
解决方法:提取每行最后两个非NA值并拼接
你说得对,paste()确实是实现这个需求的关键工具,但我们需要先对每行的非NA值做筛选和提取,再用它来完成拼接。下面给你两种可行的实现方式:
方法一:Base R 原生实现
这种方法不需要额外安装包,直接用base R的apply()函数逐行处理:
# 先构造你的数据框 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) # 定义一个处理单行的函数:提取最后两个非NA值并拼接 get_last_two <- function(row) { # 筛选当前行的非NA元素 non_na <- row[!is.na(row)] # 取最后两个元素,用空格拼接 paste(tail(non_na, 2), collapse = " ") } # 给数据框添加新列 demo_table$assignation <- apply(demo_table, 1, get_last_two)
运行后查看结果,就会得到你想要的assignation列:
print(demo_table)
方法二:Tidyverse (dplyr) 实现
如果你习惯用tidyverse风格的代码,可以用rowwise()来逐行处理:
library(dplyr) # 基于已有的demo_table,添加assignation列 demo_table <- demo_table %>% rowwise() %>% mutate( # 收集当前行所有非NA值到列表里 non_na_vals = list(c_across(everything())[!is.na(c_across(everything()))]), # 提取最后两个并拼接 assignation = paste(tail(non_na_vals, 2), collapse = " ") ) %>% ungroup() %>% select(-non_na_vals) # 移除临时中间列
关键逻辑解释
两种方法的核心思路是一致的:
- 对每行数据,先筛选出所有非NA的元素;
- 用
tail(..., 2)提取这些元素里的最后两个; - 用
paste(..., collapse = " ")把这两个元素用空格连接成字符串。
这样就能完美匹配你给出的预期输出啦!
内容的提问来源于stack exchange,提问作者Valentin
相关产品推荐
相关产品推荐

