在R中基于ifelse逻辑实现琼脂糖凝胶数据控制值列填充的问题
琼脂糖凝胶条带数据自动化匹配对照值
原始数据格式
条带检测软件输出的数据如下:
Lane Band.No. Band.Label Relative.Front 17 2 1 Wellctrl 0.057569 18 2 2 Targetctrl 0.351812 19 3 1 Well 0.066098 20 3 2 Target 0.353945 21 4 1 Well 0.063966 22 4 2 Target 0.358209 23 5 1 Well 0.059829 24 5 2 Target 0.361111 25 6 1 Well 0.068376 26 6 2 Target 0.363248 27 7 1 Well 0.064103 28 7 2 Target 0.361111 29 8 1 Well 0.070513 30 8 2 Target 0.358974 31 9 1 Wellctrl 0.074786 32 9 2 Targetctrl 0.358974 33 10 1 Well 0.053419 34 10 2 Target 0.356838 35 11 1 Well 0.061966 36 11 2 Target 0.356838 37 12 1 Well 0.061966 38 12 2 Target 0.354701 39 13 1 Well 0.062098 40 13 2 Target 0.349036 41 13 3 NonTarget 0.576017 42 14 1 Well 0.059957 43 14 2 Target 0.344754 44 14 3 NonTarget 0.580300 45 15 1 Well 0.062098 46 15 2 Target 0.342612 47 15 3 NonTarget 0.573876 48 16 1 Well 0.059957 49 16 2 Target 0.338330
需求
新增一列New,规则如下:
- 当
Band.Label为Targetctrl时,New列取当前行的Relative.Front值 - 后续所有行的
New列沿用该值,直到遇到下一个Targetctrl时更新为新的Relative.Front值 - 第一个
Targetctrl之前的行(本例中仅行17),可保留自身Relative.Front或设为NA,按需处理
最终目标效果:
Lane Band.No. Band.Label Relative.Front New 17 2 1 Wellctrl 0.057569 0.057569/NA 18 2 2 Targetctrl 0.351812 0.351812 19 3 1 Well 0.066098 0.351812 20 3 2 Target 0.353945 0.351812 21 4 1 Well 0.063966 0.351812 22 4 2 Target 0.358209 0.351812 23 5 1 Well 0.059829 0.351812 24 5 2 Target 0.361111 0.351812 25 6 1 Well 0.068376 0.351812 26 6 2 Target 0.363248 0.351812 27 7 1 Well 0.064103 0.351812 28 7 2 Target 0.361111 0.351812 29 8 1 Well 0.070513 0.351812 30 8 2 Target 0.358974 0.351812 31 9 1 Wellctrl 0.074786 0.351812 32 9 2 Targetctrl 0.358974 0.358974 33 10 1 Well 0.053419 0.358974 34 10 2 Target 0.356838 0.358974 35 11 1 Well 0.061966 0.358974 36 11 2 Target 0.356838 0.358974 37 12 1 Well 0.061966 0.358974 38 12 2 Target 0.354701 0.358974 39 13 1 Well 0.062098 0.358974 40 13 2 Target 0.349036 0.358974 41 13 3 NonTarget 0.576017 0.358974 42 14 1 Well 0.059957 0.358974 43 14 2 Target 0.344754 0.358974 44 14 3 NonTarget 0.580300 0.358974 45 15 1 Well 0.062098 0.358974 46 15 2 Target 0.342612 0.358974 47 15 3 NonTarget 0.573876 0.358974 48 16 1 Well 0.059957 0.358974 49 16 2 Target 0.338330 0.358974
当前尝试
作为R语言新手,尝试用ifelse结合apply提取Targetctrl对应的值,但仅能得到零散结果,无法实现后续行的填充:
testfunction <- function(x) { ifelse(x["Band.Label"] == "Targetctrl", x["Relative.Front"], NA) } apply(data, 1, testfunction)
输出结果:
17 18 19 20 21 22 NA "0.351812" NA NA NA NA 23 24 25 26 27 28 NA NA NA NA NA NA 29 30 31 32 33 34 NA NA NA "0.358974" NA NA 35 36 37 38 39 40 NA NA NA NA NA NA 41 42 43 44 45 46 NA NA NA NA NA NA 47 48 49 NA NA NA
解决方案
方法1:基础R实现(无需额外包)
核心思路是先标记Targetctrl对应的值,再通过循环向前填充NA:
# 1. 创建初始列:仅Targetctrl行赋值,其余为NA data$New <- ifelse(data$Band.Label == "Targetctrl", data$Relative.Front, NA) # 2. 处理第一个Targetctrl之前的行(可选,按需设为自身值或NA) first_ctrl_row <- which(data$Band.Label == "Targetctrl")[1] data$New[1:(first_ctrl_row - 1)] <- data$Relative.Front[1:(first_ctrl_row - 1)] # 替换为NA则改为NA # 3. 循环向前填充后续NA for (i in 2:nrow(data)) { if (is.na(data$New[i])) { data$New[i] <- data$New[i-1] } }
方法2:用dplyr包(更简洁高效)
如果已安装dplyr和tidyr包,代码可读性和效率更高:
library(dplyr) library(tidyr) data <- data %>% # 给Targetctrl行赋值,其余为NA mutate(New = if_else(Band.Label == "Targetctrl", Relative.Front, NA_real_)) %>% # 向下填充NA值 fill(New, .direction = "down") %>% # 处理第一个Targetctrl之前的行(可选) mutate(New = if_else(row_number() < which(Band.Label == "Targetctrl")[1], Relative.Front, New))
两种方法均可实现需求,方法2更适合日常数据处理流程。
内容的提问来源于stack exchange,提问作者BioNewb
相关产品推荐
相关产品推荐

