我正在编写一个脚本,用于标识数字向量介于两者之间的间隔。例如0.3落在第一个间隔0.5,0.8,1中。下面代码的简化示例:
a <- array(dim=10);
for(x in 1:10){
a[x] <- c(1,2,3)[apply(abs(outer(as.numeric(df[x,]), r[x], '-')),2, which.min)];
}
当r中的每个值应用于同一向量时,这很有效 - 在本例中为.numeric(df [1,])。但是,我现在需要将r中的每个值应用于数据集df中对应的唯一行。目前我正在循环中执行此操作,这似乎是无效的,但我无法找到循环遍历每一行的有效替代方法:
var temp = function (tab) {
browser.tabs.executeScript(null, { file: "src/js/asdf.js" });
};
browser.tabs.onCreated.addListener(temp);
是否有比循环更有效的替代方案?
谢谢, 詹姆斯
答案 0 :(得分:0)
正如@Gregor所说,最好使用findInterval
。您可以使用mutate_xxx
包中的dplyr
个功能在所有列上应用findInterval
library(tidyverse)
set.seed(1111)
df <- data.frame(p1 = runif(10)/2, p2 = rep(-1,10), p3 = rep(1, 10));
df$p2 <- df$p1 + runif(10)/2;
# define intervals
intv1 <- c(0.3, 0.5, 0.8, 1)
# columns start with `p`
df %>%
mutate_at(vars(starts_with("p")), funs(bin = findInterval(., intv1)))
#> p1 p2 p3 p1_bin p2_bin p3_bin
#> 1 0.23275132 0.2335964 1 0 0 4
#> 2 0.20646243 0.5809412 1 0 2 4
#> 3 0.45350161 0.8289807 1 1 3 4
#> 4 0.06855271 0.3852559 1 0 1 4
#> 5 0.36940842 0.8034923 1 1 3 4
#> 6 0.48816350 0.5678450 1 1 2 4
#> 7 0.43997997 0.8983940 1 1 3 4
#> 8 0.05839214 0.3368955 1 0 1 4
#> 9 0.27314439 0.7233537 1 0 2 4
#> 10 0.07005799 0.4530015 1 0 1 4
# selected columns only
col2select <- c("p1", "p2")
df %>%
mutate_at(col2select, funs(bin = findInterval(., intv1)))
#> p1 p2 p3 p1_bin p2_bin
#> 1 0.23275132 0.2335964 1 0 0
#> 2 0.20646243 0.5809412 1 0 2
#> 3 0.45350161 0.8289807 1 1 3
#> 4 0.06855271 0.3852559 1 0 1
#> 5 0.36940842 0.8034923 1 1 3
#> 6 0.48816350 0.5678450 1 1 2
#> 7 0.43997997 0.8983940 1 1 3
#> 8 0.05839214 0.3368955 1 0 1
#> 9 0.27314439 0.7233537 1 0 2
#> 10 0.07005799 0.4530015 1 0 1
# for all columns
df %>%
mutate_all(funs(bin = findInterval(., intv1)))
#> p1 p2 p3 p1_bin p2_bin p3_bin
#> 1 0.23275132 0.2335964 1 0 0 4
#> 2 0.20646243 0.5809412 1 0 2 4
#> 3 0.45350161 0.8289807 1 1 3 4
#> 4 0.06855271 0.3852559 1 0 1 4
#> 5 0.36940842 0.8034923 1 1 3 4
#> 6 0.48816350 0.5678450 1 1 2 4
#> 7 0.43997997 0.8983940 1 1 3 4
#> 8 0.05839214 0.3368955 1 0 1 4
#> 9 0.27314439 0.7233537 1 0 2 4
#> 10 0.07005799 0.4530015 1 0 1 4
由reprex package(v0.2.0)创建于2018-05-08。
答案 1 :(得分:0)
感谢您的建议。我使用过dplyr并提出以下内容。它似乎比我原来的更快,但是随着数据集大小的增加仍然受到影响:
library(dplyr);
# Dummy data-set
nRows <- 1000
df <- data.frame(p1 = runif(nRows )/2, p2 = rep(-1,nRows ), p3 = rep(1, nRows ), r = runif(nRows))
df$p2 <- df$p1 + runif(nRows )/2
df %>% dplyr::rowwise() %>%
dplyr::mutate_at(vars(starts_with("r")), funs(bin = 1+findInterval(., c(p1,p2,p3))))
- 詹姆斯