使用dplyr为大型DataFrame生成每行含非正值的列名列
基于dplyr提取每行含0或负值的列名
问题描述
我有一个规模极大的DataFrame,数据示例如下:
> p fu2_difftime_mridate_d_date fu2_difftime_premri fu2_difftime_prevfu fu2_difftime_fudate_d_date 1 30.4 12.7 -14.2 6.4 2 12.9 -48.1 -47.6 13.3
希望用dplyr实现:新增一列negvalues,存储每行中数值为0或负值的列名,期望输出如下:
> p negvalues fu2_difftime_premri fu2_difftime_prevfu fu2_difftime_fudate_d_date 1 "fu2_difftime_prevfu" 12.7 -14.2 6.4
数据源结构:
p <- structure(list(fu2_date = structure(c(15428, 13746), class = "Date"), fu2_mri_date = structure(c(16156, 13732), class = "Date"), fu2_difftime_mridate_d_date = c(30.4, 12.9), fu2_difftime_premri = c(12.7, -48.1), fu2_difftime_prevfu = c(-14.2, -47.6), fu2_difftime_fudate_d_date = c(6.4, 13.3)), row.names = 1:2, class = "data.frame")
解决方案
使用dplyr的行操作和列选择函数可以轻松实现需求,代码如下:
library(dplyr) # 生成negvalues列 p <- p %>% rowwise() %>% mutate(negvalues = paste( names(.)[c_across(starts_with("fu2_difftime_")) <= 0], collapse = ", " )) %>% ungroup() # 查看结果 print(p)
代码说明
rowwise():指定后续操作按行执行,确保每行单独判断c_across(starts_with("fu2_difftime_")):精准选中所有需要判断的数值列(排除日期列fu2_date、fu2_mri_date)names(.)[c_across(...) <= 0]:筛选出当前行中数值≤0的列名paste(..., collapse = ", "):如果一行有多个符合条件的列,用逗号拼接成字符串;只有一个时直接显示列名ungroup():取消行分组,恢复DataFrame的常规处理模式
如果需要和示例输出的列顺序一致,可以追加select()调整列顺序:
p <- p %>% rowwise() %>% mutate(negvalues = paste( names(.)[c_across(starts_with("fu2_difftime_")) <= 0], collapse = ", " )) %>% ungroup() %>% select(negvalues, starts_with("fu2_difftime_"))
内容的提问来源于stack exchange,提问作者cmirian
相关产品推荐
相关产品推荐

