【问题标题】:Apply a function on columns, without the result replacing the column values based on the outcome of the function在列上应用函数,而不根据函数的结果替换列值
【发布时间】:2021-01-10 05:01:07
【问题描述】:

(这基本上是图片中的数据框)

structure(list(mz = c(40, 50, 60, 70, 80, 90), 
`sample in1` = c(10, 51, 125, 99, 675, 12), 
`sample in2` = c(9, 51, 125, 105, 2424, 5),
`Sample in3` = c(1, 51, 125, 300, 1241, 0.02), 
`blank 1` = c(5, 20, 50, 68, 0, 0),
`blank 2` = c(10, 20, 50, 77, 0, 0),
`blank 3` = c(15, 20, 50, 89, 0, 0.01)), 
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

我有一个包含 50 多列和 50.000 行的大型数据框,但这是我所拥有的简化版本。

我基本上需要做的是将“空白”列汇总为 1 列。我已经设法做到了,在所有空白列上使用 RowMeans。 接下来,我想对数据框中的每个样本值应用一个函数,该函数是:该特定行的所有空白列的样本值/平均值 = 比率 SB。 棘手的部分是:我不希望这个函数的结果替换样本的列值。 我想要做的是(1)保持列值不变,如果比率 SB 大于设定的限制(例如:比率 SB>2.5,应该保持列值不变)。 OR (2) 返回 0(或 NA),以防 SB 比率的结果小于设置的限制(例如:如果 Ratio SB

这些是我的代码的 3 个基本要素。 输出应该仍然是一个数据帧,当将其应用到图 1 中显示的数据帧时,在运行我想要制作的函数时,数据帧应该会发生以下变化。

这是应用代码后的样子:

structure(list(mz = c(40, 50, 60, 70, 80, 90), 
`sample in1` = c(NA, 51, NA, NA, 675, 12), 
`sample in2` = c(NA, 51, NA, NA, 2424, 5),
`Sample in3` = c(NA, 51, NA, 300, 1241, NA), 
`Blank Average` = c(10, 20, 50, 78, NA, 0.00333333),
row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

到目前为止,我尝试使用 case_when,但为此我需要恢复为列表结构,并且无法将其明显应用于数据帧。 我也尝试过:Ratio_X

如果有任何不清楚的地方,我深表歉意,我是 R 和堆栈溢出的完整初学者。如果您需要更多信息,请告诉我。提前致谢!

【问题讨论】:

  • 图片非常适合绘图,但对于数据却毫无用处。你需要帮助编码,所以我们需要一些东西来测试和演示答案。请分享我们可以复制/粘贴到 R 中的示例数据 - 这样做的好方法是 (a) 共享代码来创建/模拟示例数据,或 (b) 使用 dput() 制作您已经复制/粘贴的数据版本有。这三列中的 5 行类似于 dput(your_data[1:5, c("mz", "blank1", "blank2")])。并请显示您的小样本输入的预期输出,以便您的目标明确。谢谢!
  • 您好 Akrun 和 Gregor,感谢您的帮助!我什至不知道 dput(),我已将代码添加到原始帖子中。这是足够的还是你需要更多的经历?我基本上想要“SB比率”功能,检查所有列值是否它们的SB比率值> 2.5(例如)。如果是这种情况,我不想更改列值,如果不是这种情况,我想用 0 或 NA 替换列值。请注意,如果“背景平均值”= 0,则列值也不应更改(因为 SB 比率 = 样本/平均空白 = 样本/0,这是不可能的)。非常感谢!

标签: r function dataframe dplyr conditional-statements


【解决方案1】:

这是一个基本的 R 方法:

#Get all the columns which has 'blank' in it
blank_cols <- grep('blank', names(df))
#Get all the columns which has 'sample' in it. 
#Using `ignore.case` because you have "Sample" in 3rd column
sample_cols <- grep('sample', names(df), ignore.case = TRUE)
#Threshold limit to check for
thresh <- 2.5

#Get mean of blank_cols
df$Blank_avg <- rowMeans(df[, blank_cols], na.rm = TRUE)
#Compare sample_cols with the mean, replace them by NA if they are below thresh
df[sample_cols][sweep(df[sample_cols], 1, df1$Blank_avg, `/`) <= thresh] <- NA
#Turn Blank_avg to NA where Blank_avg = 0
df$Blank_avg[df$Blank_avg == 0] <- NA
#Remove blank_cols
result <- df[, -blank_cols]
result
# A tibble: 6 x 5
#     mz `sample in1` `sample in2` `Sample in3` Blank_avg
#  <dbl>        <dbl>        <dbl>        <dbl>     <dbl>
#1    40           NA           NA        NA     10      
#2    50           51           51        51     20      
#3    60           NA           NA        NA     50      
#4    70           NA           NA       300     78      
#5    80          675         2424      1241     NA      
#6    90           12            5       0.02   0.00333

【讨论】:

  • 非常感谢,帮了大忙!
猜你喜欢
  • 2021-06-04
  • 2015-05-14
  • 2018-01-18
  • 2021-06-08
  • 1970-01-01
  • 2018-06-15
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多