请考虑以下代码。
set.seed(56)
library(dplyr)
df <- data.frame(
NUM_1 = sample.int(500, replace = TRUE),
DENOM_1 = sample.int(500, replace = TRUE),
NUM_2 = sample.int(500, replace = TRUE),
DENOM_2 = sample.int(500, replace = TRUE)
)
head(df)
NUM_1 DENOM_1 NUM_2 DENOM_2
1 417 379 154 173
2 160 437 239 154
3 243 315 106 361
4 291 169 393 340
5 170 450 429 421
6 422 131 75 64
无需手动指定每个列名(实际问题中我需要创建大约40个列名(,我希望为其创建FRAC_X = NUM_X/DENOM_X
的列FRAC_1
和FRAC_2
。
因此,这将是我想要的输出,但由于我要处理大约40个这样的列,我不想手动键入每一列:
df_frac <- df %>%
mutate(FRAC_1 = NUM_1 / DENOM_1,
FRAC_2 = NUM_2 / DENOM_2)
head(df_frac)
NUM_1 DENOM_1 NUM_2 DENOM_2 FRAC_1 FRAC_2
1 417 379 154 173 1.1002639 0.8901734
2 160 437 239 154 0.3661327 1.5519481
3 243 315 106 361 0.7714286 0.2936288
4 291 169 393 340 1.7218935 1.1558824
5 170 450 429 421 0.3777778 1.0190024
6 422 131 75 64 3.2213740 1.1718750
与此相比,我更喜欢dplyr
解决方案。我想也许我可以将mutate()
与across()
一起使用,但我不清楚如何告诉across()
将NUM_x
与相应的DENOM_x
列配对。
这是tidyverse
中的一个
- 循环
across
名称为starts_with
'NUM'的列 - 提取列名
cur_column()
,将str_replace
中的子字符串从"NUM"替换为"DENOM"> get
列值,除以NUM列,然后更改.names
中的列名以创建"FRAC"列
library(dplyr)
library(stringr)
df <- df %>%
mutate(across(starts_with("NUM"), ~
./get(str_replace(cur_column(), 'NUM', 'DENOM')),
.names = "{str_replace(.col, 'NUM', 'FRAC')}"))
-输出
head(df)
NUM_1 DENOM_1 NUM_2 DENOM_2 FRAC_1 FRAC_2
1 417 379 154 173 1.1002639 0.8901734
2 160 437 239 154 0.3661327 1.5519481
3 243 315 106 361 0.7714286 0.2936288
4 291 169 393 340 1.7218935 1.1558824
5 170 450 429 421 0.3777778 1.0190024
6 422 131 75 64 3.2213740 1.1718750