【发布时间】:2018-03-13 12:52:09
【问题描述】:
我很难理解如何利用 R 矢量化以更有效的方式做我想做的事。
简而言之,对于每一行,我想将当前行的第二列($start)与上一行和下一行的 $start 进行比较(所有值都是整数,我们将这些值称为 prev_dist 和 next_dist)。接下来,打印当前行的第 4 列($condition),后跟 5 个前一个 $condition 或 5 个下一个 $condition,这取决于哪个较低的距离值(即上一行或下一行的 $start 最接近当前行的 $start)。
weather 146 17 Rainy
weather 147 17 Rainy
weather 163 16 Sunny
weather 173 15 Sunny
weather 176 15 Rainy
weather 197 12 Rainy
我希望我的输出类似于(在数据框中):
Rainy Rainy Sunny Sunny Sunny Rainy
Rainy Sunny Sunny Sunny Rainy Rainy
etc.
我尝试在下面编写一个函数,但这个函数对于大型模拟数据集永远运行。
有人可以帮助我了解在这种情况下如何实现矢量化吗?
buildMatrix <- function(input){
len <- nrow(input)-6
sequence_matrix <- data.frame()
for(line in 6:len){
start <- input[line,]$start
prev_start <- input[line-1,]$start
next_start <- input[line+1,]$start
prev_dist <- abs(start-prev_start)
next_dist <- abs(start-next_start)
current_seq <- input[line,]$condition
if(prev_dist < next_dist || prev_dist == next_dist){
for(i in 1:5){
prev_seq <- input[line-i,]$condition
current_seq <- c(current_seq, prev_seq)}
} else if(prev_dist > next_dist){
for(i in 1:5){
next_seq <- input[line+i,]$condition
current_seq <- c(current_seq, next_seq)}
}
sequence_matrix <- rbind(sequence_matrix, current_seq)
}
colnames(sequence_matrix) <- c("p0", "p1", "p2", "p3", "p4", "p5")
sequence_matrix
}
修改代码:
library(dplyr)
islessthan <- abs(df$V2-lead(df$V2)) < abs(df$V2-lag(df$V2))
ans <- lapply(seq_along(islessthan), function(i) if (is.na(islessthan[i])) {
NA
} else if(islessthan[i]==FALSE) {
c(df$V4[i], head(lag(df$V4, pmax(6-i, 0)), 5))
} else {
c(df$V4[i], head(lead(df$V4, i), 5))
})
【问题讨论】:
-
而不是
$V2等——为什么不给列提供信息性名称呢?之后,您可以为prev_start和next_start创建新列(根据情况在最后一行或最后一行填充NA)。这可以在 1 行无循环语句中完成。一旦你到了那个阶段,问题就会容易得多。 -
关于命名的观点。您的意思是像上面的列修改代码(我编辑了我的问题)吗?
-
我想到的是
df$prev_start <- c(NA,head(df$start,-1))和df$next_start <- c(tail(df$start,-1),NA),尽管基于dplyr的解决方案可能更可取。
标签: r performance function vectorization large-data