我想你想要速度。
我认为数据的形式不适合计算,因为只有col1是字符,col367:370是不同的类型,而且非常广泛。也许逐行计算不是个好主意。基本上,R适合逐列计算。
如果我是你,我会准备以下表格中的数据;
library(tidyverse)
dat1 <- dat[, -c(1, 367:370)] %>%
t() %>%
as.tibble() %>%
set_names(location)
dat2 <- dat[, 367:370] %>%
t() %>%
as.tibble() %>%
set_names(location)
我建议
map2()
计算每对列。
.x
每列
dat1
和
.y
每列
dat2
(它们被视为向量)。以下代码的速度是您的50倍。
map2(dat1, dat2, ~ {
pl.val <- .y[1]
vg.val <- .y[2]
re.val <- .y[3]
me.val <- .y[4]
rain1 <- sum(.x[pl.val:vg.val])
rain2 <- sum(.x[(vg.val+ 1):re.val])
rain3 <- sum(.x[(re.val + 1):me.val])
c(rain1 = rain1, rain2 = rain2, rain3 = rain3)
}
)
[添加NL(应用,映射)]
注:对于
apply()
治疗
data.frame
由于转换为矩阵而具有字符和数字。所以如果你使用
应用()
,需要删除位置列。
apply(dat[,-1], MARGIN = 1, function(x){
pl.val <- x[367 - 1]
vg.val <- x[368 - 1]
re.val <- x[369 - 1]
me.val <- x[370 - 1]
rain1 <- sum(x[pl.val:vg.val])
rain2 <- sum(x[(vg.val+ 1):re.val])
rain3 <- sum(x[(re.val + 1):me.val])
c(rain1 = rain1, rain2 = rain2, rain3 = rain3)
})
mapply()
基本上与
map2()
. 在这个问题上,
mapply()
提供最佳性能。
mapply(function(.x, .y){
pl.val <- .y[1]
vg.val <- .y[2]
re.val <- .y[3]
me.val <- .y[4]
rain1 <- sum(.x[pl.val:vg.val])
rain2 <- sum(.x[(vg.val+ 1):re.val])
rain3 <- sum(.x[(re.val + 1):me.val])
c(rain1 = rain1, rain2 = rain2, rain3 = rain3)
}, dat1, dat2)
[基准]
Unit: microseconds
expr min lq mean median uq max neval cld
forloop_method() 14154.075 15074.555 17110.4060 16588.1200 18416.387 25869.836 100 c
map2_method() 205.586 234.263 325.8762 313.9395 333.633 2072.911 100 a
apply_method() 1617.443 1684.812 1913.9187 1783.2480 1933.216 4189.687 100 b
mapply_method() 154.972 185.079 213.9370 210.2300 225.978 468.690 100 a
[附加2(错误处理)]
当没有NA时,下面的代码几乎和上面的代码一样快。(注意:如果在一行中,可以省略
{}
属于
if(...) { A } else { B }
例如
if(...) A else B
.)
results <- map2(dat1, dat2, ~ {
pl.val <- .y[1]
vg.val <- .y[2]
re.val <- .y[3]
me.val <- .y[4]
rain1 <- if(is.na(pl.val) | is.na(vg.val)) NA else sum(.x[pl.val:vg.val], na.rm = T)
rain2 <- if(is.na(vg.val) | is.na(re.val)) NA else sum(.x[(vg.val+ 1):re.val], na.rm = T)
rain3 <- if(is.na(re.val) | is.na(me.val)) NA else sum(.x[(re.val + 1):me.val], na.rm = T)
c(rain1 = rain1, rain2 = rain2, rain3 = rain3)
}
)
# If you want data.frame instead of list
invoke("rbind", results)