我觉得有比此代码更聪明/更有效的方法:
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]))
}
也许与%>%?但是如何?
答案 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)
答案 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