R:将以 "stage" 开头的列中的所有值除以名为 time: rowwise 的列中的值

R: Divide all values in columns starting with "stage" by values in a column called time: rowwise

我有一个数据框 df,其中包含一组列中的时间和值列,这些列称为阶段 1、阶段 2,...,stage_50。我想将 stage_1 到 stage_50 列中的所有值除以时间列中的相应值。

df<-data.frame(time=runif(10)*60,stage_1=runif(10)*10,stage_2=runif(10)*10, someOtherColumn=rep("A",10))

我可以 select 名为 stage 的列并将它们放在另一个 df 中。

df1<-df %>%
select(starts_with("stage")

然后划分:

df1/df$time

但这似乎不太令人满意。我如何在 mutate 中使用 starts_with

例如

df%>%
mutate(starts_with("stage")/time)

1) across 使用 across:

library(dplyr)

df %>% mutate(across(starts_with("stage"), ~ . / time))

也可以这样写:

df %>% mutate(across(starts_with("stage"), `/`, time))

2) pivot 另一种方法是重塑成长形,执行除法,然后重塑回来。

library(dplyr)
library(tidyr)

df %>%
  pivot_longer(starts_with("stage")) %>%
  mutate(value = value / time) %>%
  pivot_wider

3) base R 它也可以很容易地在 base R 中完成:

ok <- startsWith(names(df), "stage")
replace(df, ok, df[ok] / df$time)

4) ftransformv collapse 包中有 ftransformv 可以将指定的函数应用于选定的列。它是用 C/C++ 编写的,运行速度比基本解决方案快 13 倍,比 dplyr 解决方案快 112 倍,比 tidyr 解决方案快 363 倍。

library(collapse)
ftransformv(df, startsWith(names(df), "stage"), `/`, time)