Воспроизводимый пример кода, который я пытаюсь прорисовать.
cutOffs <- seq(1,10,0.2)
plotOutput <- matrix(nrow=length(cutOffs), ncol=2)
colnames(plotOutput) <- c("x","y")
plotOutput[,"y"] <- cutOffs
for(plotPoint in 1:length(cutOffs))
{
plotOutput[plotPoint, "x"] <-
nrow(iris[ which(iris$Sepal.Length > cutOffs[plotPoint] &
iris$Sepal.Width > cutOffs[plotPoint]), ])
}
plotOutput
В частности, я хочу узнать, есть ли способ для векторизации этой части.
nrow(iris[ which(iris$Sepal.Length > cutOffs[plotPoint] &
iris$Sepal.Width > cutOffs[plotPoint]), ])
Скажем, я должен был использовать библиотеку plyr или какую-то форму приложения, вероятно, не так много ускоряется, и это действительно то, что я ищу. В сущности, я пытаюсь понять, есть ли какая-то техника для векторизации, которую я пропустил или сумел пропустить во время поиска.
UPDATE:
Unit: milliseconds
expr min lq mean median uq max neval
op() 33663.39700 33663.39700 33663.39700 33663.39700 33663.39700 33663.39700 1
jr() 3976.53088 3976.53088 3976.53088 3976.53088 3976.53088 3976.53088 1
dd() 4253.21050 4253.21050 4253.21050 4253.21050 4253.21050 4253.21050 1
exp() 5085.45331 5085.45331 5085.45331 5085.45331 5085.45331 5085.45331 1
nic() 8719.82043 8719.82043 8719.82043 8719.82043 8719.82043 8719.82043 1
sg() 16.66177 16.66177 16.66177 16.66177 16.66177 16.66177 1
Более реалистичное приближение того, что я на самом деле делаю, это
# generate data
numObs <- 1e5
iris <- data.frame( Sepal.Length = sample(1:numObs), Sepal.Width = sample(1:numObs) )
cutOffs <- 1:(numObs*0.01)
plotOutput <- matrix(nrow=length(cutOffs), ncol=2)
colnames(plotOutput) <- c("x","y")
plotOutput[,"y"] <- cutOffs
за которым следует какой-либо конкретный метод, который предпочитают.
В общем случае он будет использоваться на наборах данных с 50 000 - 200 000 точек.
Был большой прыжок от использования
sum(Sepal.Length > cutOffs[plotPoint] & Sepal.Width > cutOffs[plotPoint])
это то, чего я раньше не встречал, как более оптимальный подход.
В то же время лучшим ответом является sgibb sg(). Ключ понимает, что это имеет значение только самое низкое из двух значений в каждой строке. После того, как этот умственный скачок был сделан, только один вектор, оставленный для обработки и векторизации, достаточно прост.
# cutOff should be lower than the lowest of Sepal.Length & Sepal.Width
m <- pmin(iris$Sepal.Length, iris$Sepal.Width)