R语言技术求助:如何为数据框每行添加首、末负值对应的列名列
问题分析与解决方案
你的代码主要存在两个核心问题:
- 原数据是字符型矩阵,直接用
dat<0会因类型不匹配导致负数判断错误(比如字符串形式的负数无法被正确识别为数值型负数); max.col的逻辑不符合需求:它是用来查找每行最大值的位置,而我们需要的是定位每行中第一个/最后一个负值的位置,两者逻辑完全不同。
下面是具体的修正方案:
步骤1:将字符型数据转换为数值型矩阵
首先需要把原数据里的字符型数值转换成数值类型,才能正确判断正负:
# 逐列转换为数值型,自动处理NA dat_num <- apply(dat, 2, as.numeric) # 保留原数据的行名和列名 rownames(dat_num) <- rownames(dat) colnames(dat_num) <- colnames(dat)
步骤2:提取每行第一个和最后一个负值的列名
我们可以用apply逐行处理,先找出每行中负值的列索引,再分别取第一个和最后一个对应的列名:
# 提取每行第一个负值的列名,无负值则返回NA dat$firststatus <- apply(dat_num, 1, function(x) { neg_cols <- which(x < 0 & !is.na(x)) if (length(neg_cols) == 0) NA else colnames(dat_num)[neg_cols[1]] }) # 提取每行最后一个负值的列名,无负值则返回NA dat$laststatus <- apply(dat_num, 1, function(x) { neg_cols <- which(x < 0 & !is.na(x)) if (length(neg_cols) == 0) NA else colnames(dat_num)[neg_cols[length(neg_cols)]] })
完整测试代码
把你的原数据和解决方案整合起来验证:
# 你的原始数据 dat <- structure(c(NA, NA, "11", "-8.01e-14", NA, "6", NA, "-3", "-7", NA, NA, NA, NA, "3", "-5.0015e-8", NA, NA, NA, NA, "-4.5e+00", NA, "50.5", "51", "51", "50.5", "53", "52"), .Dim = c(3L, 9L), .Dimnames = list( c("1001", "1002", "1003"), c("50", "50.5", "51", "51.5", "52", "52.5", "53", "firststatus", "laststatus"))) # 转换为数值矩阵 dat_num <- apply(dat, 2, as.numeric) rownames(dat_num) <- rownames(dat) colnames(dat_num) <- colnames(dat) # 添加目标列 dat$firststatus <- apply(dat_num, 1, function(x) { neg_cols <- which(x < 0 & !is.na(x)) if(length(neg_cols) == 0) NA else colnames(dat_num)[neg_cols[1]] }) dat$laststatus <- apply(dat_num, 1, function(x) { neg_cols <- which(x < 0 & !is.na(x)) if(length(neg_cols) == 0) NA else colnames(dat_num)[neg_cols[length(neg_cols)]] }) # 查看结果 print(dat)
运行后会得到符合预期的结果:
50 50.5 51 51.5 52 52.5 53 firststatus laststatus 1001 NA -8.01e-14 NA NA NA NA NA 50.5 50.5 1002 NA NA -3 NA 3 NA -4.5 51 53 1003 "11" "6" -7 NA -5.0015e-8 NA NA 51 52.5
内容的提问来源于stack exchange,提问作者Lisa
相关产品推荐
相关产品推荐

