创建一个向量,其值具有另一个向量中不同值的计数

问题描述 投票:0回答:2

假设我有以下向量:

dat <- c(1,0,-1,1,0,-1,1,0,1)

我想要一个向量计算在dat中出现1,0和-1的数据但是作为一个持续的计数器。解决方案看起来像这样:

tally <- c(1,1,1,2,2,2,3,3,4)

所以基本上我的新矢量从dat开始持续计数为1,0和-1。我正在寻找一种在R中进行此计算的方法,因此我可以在更大的集合上使用它。

r vector counter
2个回答
1
投票

这是一个相当简单的方法:

> dat <- c(1,0,-1,1,0,-1,1,0,1)
> tally <- ave(dat, factor(dat), FUN=seq_along)
> tally
[1] 1 1 1 2 2 2 3 3 4

ave函数将dat向量除以dat中的唯一值(在本例中为-1,0和1),然后seq_along是一种快速而肮脏的方法来获取每个唯一值的运行计数,然后ave将单独的值分开累积计数按顺序重新匹配原始数据。


1
投票
dat <- c(1,0,-1,1,0,-1,1,0,1)

new_vec <- NULL
count_this <- function(vec) {
    for(i in 1:length(vec)) {
    this_elem = vec[i]
    before_vec <- vec[1:i]
    contains_vec <- before_vec[before_vec == this_elem]
    new_vec[i] <- length(contains_vec)
    }
    return(new_vec)
}

使用这样:

count_this(dat)

1 1 1 2 2 2 3 3 4

但绝对使用Greg更有效的方法:

dat_long <- round(rnorm(10000), 0)

start.time <- Sys.time()
res_a <- count_this(dat_long)
end.time <- Sys.time()
time.taken <- end.time - start.time
p_1 <- as.vector(time.taken)

start.time <- Sys.time()
res_b <- ave(dat_long, factor(dat_long), FUN=seq_along)
end.time <- Sys.time()
time.taken <- end.time - start.time
p_2 <- as.vector(time.taken)

final <- data.frame(For_Loop = p_1, Vectorized = p_2)
mp <- barplot(as.matrix(final), col='steelblue', beside=T, main='Runtimes for Tally Algoritm')

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.