函数中的 R 向量化实现
R vectorization implementation in a function
我无法理解如何利用 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))
})
利用 dplyr::lead/lag
功能发挥你的优势
您的数据
df <- read.table(text="weather 146 17 Rainy
weather 147 17 Rainy
weather 163 16 Sunny
weather 173 15 Sunny
weather 176 15 Rainy
weather 197 12 Rainy", header=FALSE, stringsAsFactors=F)
判断每一行(0行)是否有+1-row < -1-row
library(dplyr)
islessthan <- lead(df$V2) < lag(df$V2)
# [1] NA FALSE FALSE FALSE FALSE NA
使用 lapply
遍历上面创建的逻辑向量和您的数据框。 is.na(row) == TRUE
将 return NA
的行; islessthan == FALSE
的行 return 0-row + +5-rows of column V4
;以及 islessthan == TRUE
将 return -5-rows of column V4 + 0-row
的行
ans <- lapply(seq_along(islessthan), function(i) if (is.na(islessthan[i])) {
NA
} else if(islessthan[i]==FALSE) {
c(df$V4[i], head(lead(df$V4, i), 6))
} else {
c(head(lag(df$V4, 6-i), 6))
})
输出
# [[1]]
# [1] NA
# [[2]]
# [1] "Rainy" "Sunny" "Sunny" "Rainy" "Rainy" NA NA
# [[3]]
# [1] "Sunny" "Sunny" "Rainy" "Rainy" NA NA NA
# [[4]]
# [1] "Sunny" "Rainy" "Rainy" NA NA NA NA
# [[5]]
# [1] "Rainy" "Rainy" NA NA NA NA NA
# [[6]]
# [1] NA
请注意,您尚未指定如何处理边缘情况(第 1 行和第 N 行),并且您的示例没有足够的观察结果来 return 一个完整的向量,因此, NA
s 作为填充符出现在输出中。
我无法理解如何利用 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))
})
利用 dplyr::lead/lag
功能发挥你的优势
您的数据
df <- read.table(text="weather 146 17 Rainy
weather 147 17 Rainy
weather 163 16 Sunny
weather 173 15 Sunny
weather 176 15 Rainy
weather 197 12 Rainy", header=FALSE, stringsAsFactors=F)
判断每一行(0行)是否有+1-row < -1-row
library(dplyr)
islessthan <- lead(df$V2) < lag(df$V2)
# [1] NA FALSE FALSE FALSE FALSE NA
使用 lapply
遍历上面创建的逻辑向量和您的数据框。 is.na(row) == TRUE
将 return NA
的行; islessthan == FALSE
的行 return 0-row + +5-rows of column V4
;以及 islessthan == TRUE
将 return -5-rows of column V4 + 0-row
ans <- lapply(seq_along(islessthan), function(i) if (is.na(islessthan[i])) {
NA
} else if(islessthan[i]==FALSE) {
c(df$V4[i], head(lead(df$V4, i), 6))
} else {
c(head(lag(df$V4, 6-i), 6))
})
输出
# [[1]]
# [1] NA
# [[2]]
# [1] "Rainy" "Sunny" "Sunny" "Rainy" "Rainy" NA NA
# [[3]]
# [1] "Sunny" "Sunny" "Rainy" "Rainy" NA NA NA
# [[4]]
# [1] "Sunny" "Rainy" "Rainy" NA NA NA NA
# [[5]]
# [1] "Rainy" "Rainy" NA NA NA NA NA
# [[6]]
# [1] NA
请注意,您尚未指定如何处理边缘情况(第 1 行和第 N 行),并且您的示例没有足够的观察结果来 return 一个完整的向量,因此, NA
s 作为填充符出现在输出中。