R 如何创建一个循环和/或一个函数,将200列(并创建200个新列/变量)除以另一列以获得百分比?

R 如何创建一个循环和/或一个函数,将200列(并创建200个新列/变量)除以另一列以获得百分比?,r,function,loops,R,Function,Loops,如何创建一个循环和/或一个函数,将200列(并创建200个新列/变量)除以另一列以获得百分比 如何在循环中执行此操作,以便可以执行200列?我该如何命名这个名字 对列进行命名,使其成为前面带有“p_”的旧列名? 这可能吗 例如,我正在尝试这样做,但有200列 fans <- data.frame( population = c(1234, 5678, 2345, 6789, 3456, 7890, 4567, 8901, 5678, 9012, 6789

如何创建一个循环和/或一个函数,将200列(并创建200个新列/变量)除以另一列以获得百分比

如何在循环中执行此操作,以便可以执行200列?我该如何命名这个名字 对列进行命名,使其成为前面带有“p_”的旧列名? 这可能吗

例如,我正在尝试这样做,但有200列

fans <- data.frame(
  population = c(1234, 5678, 2345, 6789, 3456, 7890,
                4567, 8901, 5678, 9012, 6789),
  bearsfans = c(123, 234, 345, 456, 567,678, 789, 890, 901, 135, 246),
  packersfans = c(11,22,33,44,55,66,77,88,99,100,122),
  vikingsfans = c(39, 49, 59, 61, 32, 22, 31, 92, 52, 10, 122))

print(fans)

attach(fans)

## create new columns which are the ratio of fans to population

fans$p_bearsfan = bearsfans/population
print(fans)


 Output:
 ##     population bearsfans packersfans vikingsfans p_bearsfan
 ##  1        1234       123          11          39 0.09967585
 ##  2        5678       234          22          49 0.04121169
风扇数据

fans
temp如果您对新列名的后缀(而不是前缀)感到满意,那么这是一个使用
dplyr::mutate_at
的单行程序。这里我假设所有相关列都以单词
“fans”
结尾

带后缀 带前缀 要将后缀转换为前缀,需要执行更多步骤

fans %>%
    mutate_at(vars(ends_with("fans")), list(percent = ~.x / population)) %>%
    rename_at(vars(ends_with("percent")), ~sub("(.+)_percent", "p_\\1", .x))
#   population bearsfans packersfans vikingsfans p_bearsfans p_packersfans
#1        1234       123          11          39  0.09967585   0.008914100
#2        5678       234          22          49  0.04121169   0.003874604
#3        2345       345          33          59  0.14712154   0.014072495
#4        6789       456          44          61  0.06716748   0.006481072
#5        3456       567          55          32  0.16406250   0.015914352
#6        7890       678          66          22  0.08593156   0.008365019
#7        4567       789          77          31  0.17276111   0.016860083
#8        8901       890          88          92  0.09998877   0.009886530
#9        5678       901          99          52  0.15868263   0.017435717
#10       9012       135         100          10  0.01498003   0.011096316
#11       6789       246         122         122  0.03623509   0.017970246
#   p_vikingsfans
#1    0.031604538
#2    0.008629799
#3    0.025159915
#4    0.008985123
#5    0.009259259
#6    0.002788340
#7    0.006787826
#8    0.010335917
#9    0.009158154
#10   0.001109632
#11   0.017970246

我们可以用一列直接划分多个列。我们使用
grep
选择以
“fans”
结尾的列,并使用这些名称分配新列

cols <- grep("fans$", names(fans), value = TRUE)
fans[paste0("p_", cols)] <- fans[cols]/fans$population

fans
#   population bearsfans packersfans vikingsfans p_bearsfans p_packersfans p_vikingsfans
#1        1234       123          11          39     0.09968      0.008914      0.031605
#2        5678       234          22          49     0.04121      0.003875      0.008630
#3        2345       345          33          59     0.14712      0.014072      0.025160
#4        6789       456          44          61     0.06717      0.006481      0.008985
#5        3456       567          55          32     0.16406      0.015914      0.009259
#6        7890       678          66          22     0.08593      0.008365      0.002788
#7        4567       789          77          31     0.17276      0.016860      0.006788
#8        8901       890          88          92     0.09999      0.009887      0.010336
#9        5678       901          99          52     0.15868      0.017436      0.009158
#10       9012       135         100          10     0.01498      0.011096      0.001110
#11       6789       246         122         122     0.03624      0.017970      0.017970

col有两个嵌套循环(
apply
for
中)是不必要的,并且会产生不必要的开销。事实上,这里不需要应用
apply
,因为R
/
中的简单除法已经矢量化了。[续]因此
for
循环将变成
for(c In names(fans)[2:ncol(fans)])fans[[paste0(“p_,c)]@MauritsEvers是的,这是非常低效的-我意识到这一点。编辑了我的帖子。@MauritsEvers出于好奇,我用
apply
检查了解决方案的速度。它仍然比
mutate
快近10倍(但比naive loop over columns慢3倍——这是该线程中发布的所有测试中速度最快的一个)。您应该在答案中包含这些基准测试的结果。我相信这将是有趣的OP和未来的读者。我当然会感兴趣的。我毫不奇怪,
mutate\u at
不是最快的方法
tidyverse
方法通常更多的是关于代码可读性(甚至有些人会对此提出质疑),而不是关于速度。谢谢。这很有帮助。我可能不应该在变量名中添加风扇,而只是考虑列。我的变量确实有一组具有相同后缀的名称,但不是所有的,而且每个组的后缀都不同。有些列的名称完全不同。是否有方法仅通过列号来执行此操作,并且仍然在变量名的开头或结尾添加“p_2;”字符?@shp5009确定;可以直接指定列号。例如,
fans%>%mutate_at(2:3,list(percent=~.x/population))
仅基于列
2:3
创建新的百分比列。太棒了,它成功了!非常感谢。我知道必须有一个简单的方法来做,但我对函数是新手。欢迎。请注意,您只能将一个答案标记为已接受,但请随意选择您最喜欢的答案。:)知道了。我是新手:)@shp5009虽然您只能选择一个答案作为接受答案,但您可以随意向上投票;-)没错,但你需要15个名声。2点开始!我对这个问题投了赞成票。还有你的答案;)
temp <- sapply(fans[-1], function(x) x / fans$population)
colnames(temp) <- paste0("p_", colnames(temp))
cbind(fans, temp)



population bearsfans packersfans vikingsfans p_bearsfans p_packersfans p_vikingsfans
1        1234       123          11          39  0.09967585   0.008914100   0.031604538
2        5678       234          22          49  0.04121169   0.003874604   0.008629799
3        2345       345          33          59  0.14712154   0.014072495   0.025159915
4        6789       456          44          61  0.06716748   0.006481072   0.008985123
5        3456       567          55          32  0.16406250   0.015914352   0.009259259
6        7890       678          66          22  0.08593156   0.008365019   0.002788340
7        4567       789          77          31  0.17276111   0.016860083   0.006787826
8        8901       890          88          92  0.09998877   0.009886530   0.010335917
9        5678       901          99          52  0.15868263   0.017435717   0.009158154
10       9012       135         100          10  0.01498003   0.011096316   0.001109632
11       6789       246         122         122  0.03623509   0.017970246   0.017970246
fans %>% mutate_at(vars(ends_with("fans")), list(percent = ~.x / population))
#   population bearsfans packersfans vikingsfans bearsfans_percent
#1        1234       123          11          39        0.09967585
#2        5678       234          22          49        0.04121169
#3        2345       345          33          59        0.14712154
#4        6789       456          44          61        0.06716748
#5        3456       567          55          32        0.16406250
#6        7890       678          66          22        0.08593156
#7        4567       789          77          31        0.17276111
#8        8901       890          88          92        0.09998877
#9        5678       901          99          52        0.15868263
#10       9012       135         100          10        0.01498003
#11       6789       246         122         122        0.03623509
#   packersfans_percent vikingsfans_percent
#1          0.008914100         0.031604538
#2          0.003874604         0.008629799
#3          0.014072495         0.025159915
#4          0.006481072         0.008985123
#5          0.015914352         0.009259259
#6          0.008365019         0.002788340
#7          0.016860083         0.006787826
#8          0.009886530         0.010335917
#9          0.017435717         0.009158154
#10         0.011096316         0.001109632
#11         0.017970246         0.017970246
fans %>%
    mutate_at(vars(ends_with("fans")), list(percent = ~.x / population)) %>%
    rename_at(vars(ends_with("percent")), ~sub("(.+)_percent", "p_\\1", .x))
#   population bearsfans packersfans vikingsfans p_bearsfans p_packersfans
#1        1234       123          11          39  0.09967585   0.008914100
#2        5678       234          22          49  0.04121169   0.003874604
#3        2345       345          33          59  0.14712154   0.014072495
#4        6789       456          44          61  0.06716748   0.006481072
#5        3456       567          55          32  0.16406250   0.015914352
#6        7890       678          66          22  0.08593156   0.008365019
#7        4567       789          77          31  0.17276111   0.016860083
#8        8901       890          88          92  0.09998877   0.009886530
#9        5678       901          99          52  0.15868263   0.017435717
#10       9012       135         100          10  0.01498003   0.011096316
#11       6789       246         122         122  0.03623509   0.017970246
#   p_vikingsfans
#1    0.031604538
#2    0.008629799
#3    0.025159915
#4    0.008985123
#5    0.009259259
#6    0.002788340
#7    0.006787826
#8    0.010335917
#9    0.009158154
#10   0.001109632
#11   0.017970246
cols <- grep("fans$", names(fans), value = TRUE)
fans[paste0("p_", cols)] <- fans[cols]/fans$population

fans
#   population bearsfans packersfans vikingsfans p_bearsfans p_packersfans p_vikingsfans
#1        1234       123          11          39     0.09968      0.008914      0.031605
#2        5678       234          22          49     0.04121      0.003875      0.008630
#3        2345       345          33          59     0.14712      0.014072      0.025160
#4        6789       456          44          61     0.06717      0.006481      0.008985
#5        3456       567          55          32     0.16406      0.015914      0.009259
#6        7890       678          66          22     0.08593      0.008365      0.002788
#7        4567       789          77          31     0.17276      0.016860      0.006788
#8        8901       890          88          92     0.09999      0.009887      0.010336
#9        5678       901          99          52     0.15868      0.017436      0.009158
#10       9012       135         100          10     0.01498      0.011096      0.001110
#11       6789       246         122         122     0.03624      0.017970      0.017970