比使用“ for”循环更有效的方法

时间:2018-11-26 05:02:45

标签: r

我觉得有比此代码更聪明/更有效的方法:

df <- mtcars

df$somename <- as.array(rep(c(0), 32))

for (i in 1:32){
  df$somename[i] <- sd(c(df$wt[i], df$qsec[i]))
}

也许与%>%?但是如何?

3 个答案:

答案 0 :(得分:4)

使用purrr::map2

的选项
library(tidyverse)
mtcars %>% mutate(somename = map2(wt, qsec, ~sd(c(.x, .y))))
#    mpg cyl  disp  hp drat    wt  qsec vs am gear carb somename
#1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 9.786358
#2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 10.00203
#3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 11.51877
#4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 11.47281
#5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2  9.60251
#6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 11.85111
#7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4   8.6762
#8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 11.88646
#9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 13.96536
#10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4 10.50761
#11 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4 10.93187
#12 16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3 9.425733
#13 17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3 9.807571
#14 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3 10.05506
#15 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4 9.001469
#16 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4 8.765296
#17 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4 8.538314
#18 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1 12.21173
#19 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2 11.95364
#20 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1 12.77388
#21 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1 12.40619
#22 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2 9.439876
#23 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2 9.804036
#24 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4 8.181225
#25 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2 9.337345
#26 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1 11.99607
#27 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2 10.29547
#28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2 10.88025
#29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4  8.01152
#30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6 9.001469
#31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8 7.799388
#32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2 11.18643

更新

我使用更大的数据集重新运行@ 42-的microbenchmark分析

library(microbenchmark)
df <- do.call(rbind, lapply(1:100, function(x) mtcars))
res <- microbenchmark(
    orig = {
        df$somename <- as.array(rep(c(0), nrow(df)))
        for (i in 1:nrow(df)) {
            df$somename[i] <- sd(c(df$wt[i], df$qsec[i]))}},
    tidy = {
        df <- df %>% mutate(somename = map2(wt, qsec, ~sd(c(.x, .y))))},
    mapply = {
        df$somename <- mapply(function(x, y) sd(c(x, y)), df$wt, df$qsec)},
    rowMeans = {
        df$rm <- rowMeans(df[,c("wt","qsec")])
        df$sd2col <- sqrt( (df$wt - df$rm)^2 + (df$qsec - df$rm)^2 )})
res
#Unit: microseconds
#     expr       min         lq        mean      median          uq        max
#     orig 331092.86 349754.808 360716.6501 357229.3920 366635.2820 446581.924
#     tidy 168701.28 181079.910 189710.1927 187026.6290 194392.5190 273725.354
#   mapply 161711.77 172457.395 179326.5484 177263.3045 183688.5365 266102.901
# rowMeans    228.08    315.854    343.9151    334.8975    358.5915    807.847

library(ggplot2)
autoplot(res)

enter image description here

答案 1 :(得分:2)

评论多于答案:

> library(microbenchmark)
> microbenchmark(  orig = {df <- mtcars
+ 
+ df$somename <- as.array(rep(c(0), 32))
+ 
+ for (i in 1:32){
+     df$somename[i] <- sd(c(df$wt[i], df$qsec[i]))
+ }},  tidy = {
+     mtcars %>% mutate(somename = map2(wt, qsec, ~sd(c(.x, .y))))}, mapply = { mapply(function(x, y) sd(c(x, y)), df$wt, df$qsec)})

#------------------------------------
Unit: microseconds
   expr      min        lq      mean   median        uq       max neval cld
   orig 5069.391 5161.9270 5555.5886 5236.769 5490.7365 12400.502   100   b
   tidy  910.071  943.9685  986.4419  970.541  998.8075  1241.711   100  a 
 mapply  744.639  761.1875  805.6328  773.426  807.2545  2206.393   100  a 

答案 2 :(得分:2)

代码:

df $ somename <-apply(matrix(c(df $ wt,df $ qsec),ncol = 2),MARGIN = 1,FUN = sd)

输出:

0