样机数据
由于您没有提供一些数据,我按照您提供的描述创建了一些模型数据。这里:
set.seed(1)
Volume <- data.frame(ID = sample(letters, 30, TRUE),
GR = sample(LETTERS, 30, TRUE))
Volume[3:10] <- rnorm(30*8)
Dplyr 解决方案
library(dplyr)
# rename columns [brute force]
cols <- c("Volume_OD","Volume_Imp","Volume_OD_1","Volume_WS_1","Volume_OD_2","Volume_WS_2","Volume_OD_3","Volume_WS_3")
colnames(Volume)[3:10] <- cols
# divide by Volumn_OD
rel.Volume_unmod <- Volume %>%
mutate(across(all_of(cols), ~ . / Volume_OD))
# result
rel.Volume_unmod
说明
- 我不知道您的列的名称。这些名称可能与您打算在
rel.Volume_unmod 中创建的列的名称相对应。无论如何,为了避免任何问题,我重命名了这些列(有点残忍)。如果您愿意,可以使用dplyr::rename 进行操作。
- 有很多方法可以选择您想要
mutate 的列。 mutate 是来自 dplyr 的动词,允许您创建新列或对列执行操作或功能。
-
across 是来自dplyr 的副词。让我们通过说它是一个允许您在多个列上执行函数的函数来简化。在这种情况下,我想通过Volum_OD 进行除法。
-
~ 是 tidyverse 创建匿名函数的方法。 ~ . / Volum_OD 等价于 function(x) x / Volumn_OD
-
all_of 是必要的,因为在这种特定情况下,我为 across 提供了一个字符向量。没有它,它仍然可以工作,但您会收到警告,因为它不明确,并且在相同情况下可能无法正常工作。
更多信息
查看this book 以了解有关使用tidyverse(dplyr 是其中的一部分)进行数据操作的更多信息。
Base-R 解决方案
rel.Volume_unmod <- Volume
# rename columns
cols <- c("Volume_OD","Volume_Imp","Volume_OD_1","Volume_WS_1","Volume_OD_2","Volume_WS_2","Volume_OD_3","Volume_WS_3")
colnames(rel.Volume_unmod)[3:10] <- cols
# divide by columns 3
rel.Volume_unmod[3:10] <- lapply(rel.Volume_unmod[3:10], `/`, rel.Volume_unmod[3])
rel.Volume_unmod
说明
-
lapply 是一个基础 R 函数,可让您将函数应用于列表或“可列出”对象的每个项目。
- 在这种情况下,
rel.Volume_unmod 是一个可列出的对象:数据帧只是一个具有相同长度的向量列表。因此,lapply 一次占用一列 [= 一项] 并应用一个函数。
- 函数是
/。你通常会看到/ 是这样使用的:A / B,但实际上/ 是一个 Primitive 函数。你可以这样写同样的东西:
`/`(A, B) # same as A / B
-
lapply 可以提供附加参数,这些参数直接传递给应用于列表的函数(在本例中为 /)。因此,我们将rel.Volume_unmod[3] 写为附加参数。
-
lapply 总是返回一个列表。但是,由于我们将 lapply 的结果分配给“数据框的一部分”,我们将只编辑数据框的列,因此,我们将有一个数据框而不是列表。让我以更技术性的方式重新表述。当您分配rel.Volume_unmod[3:10] <- lapply(...) 时,您不只是将列表分配给rel.Volume_unmod[3:10]。从技术上讲,您正在使用此分配功能:[<-。这是一个允许编辑列表/向量/数据框中的项目的功能。具体来说,[<- 允许您在不修改列表/向量/数据框的属性的情况下分配新项目。正如我之前所说,数据框只是具有特定属性的列表。然后,当您使用 [<- 时,您会修改列,但不会更改属性(在本例中为类 data.frame)。这就是魔法起作用的原因。