向量中不同元素之间的元素数量计数

9
假设我有一个值的向量,例如:
A C A B A C C B B C C A A A B B B B C A

我希望您能创建一个新的向量,对于每个元素,它包含自上次出现以来的元素数量。因此,对于上面的向量,
NA NA  2 NA  2  4  1  4  1  3  1  7  1  1  6  1  1  1  8  6

(其中NA表示这是第一次看到该元素。)
例如,第一个和第二个A分别在位置1和3,相差2;第三个和第四个A分别在位置4和11,相差7,以此类推。
是否有预先构建的管道兼容函数可以执行此操作?
我拼凑了这个函数来演示:
# For reproducibility
set.seed(1)

# Example vector
x = sample(LETTERS[1:3], size = 20, replace = TRUE)


compute_lag_counts = function(x, first_time = NA){
  # return vector to fill
  lag_counts = rep(-1, length(x))
  # values to match
  vals = unique(x)
  # find all positions of all elements in the target vector
  match_list = grr::matches(vals, x, list = TRUE)
  # compute the lags, then put them in the appropriate place in the return vector
  for(i in seq_along(match_list))
    lag_counts[x == vals[i]] = c(first_time, diff(sort(match_list[[i]])))
  
  # return vector
  return(lag_counts)
}

compute_lag_counts(x)

虽然它似乎完成了它应该完成的任务,但我更愿意使用别人高效、经过充分测试的解决方案!我的搜索结果为空,这让我感到惊讶,因为这似乎是一个常见的任务。

3个回答

8

或者

ave(seq.int(x), x, FUN = function(x) c(NA, diff(x)))
#  [1] NA NA  2 NA  2  4  1  4  1  3  1  7  1  1  6  1  1  1  8  6

我们计算每个组的x索引的第一个diff差异。
感谢@Henrik提供的data.table选项。
library(data.table)
dt = data.table(x)
dt[ , d := .I - shift(.I), x]
dt

4
我正在撰写一个类似的data.table替代方案,但你比我更快:dt = data.table(x)dt[ , d := .I - shift(.I), x] - Henrik

3

这是一个可行的函数

compute_lag_counts <- function(x) {
  seqs <- split(seq_along(x), x)
  unsplit(Map(function(i) c(NA, diff(i)), seqs), x)
}

compute_lag_counts (x)
# [1] NA NA  2 NA  2  4  1  4  1  3  1  7  1  1  6  1  1  1  8  6

基本上,您可以使用split()将向量中每个唯一值的索引位置分开。然后我们使用它们出现的索引之间的差异来计算到前一个值的距离。最后,我们使用unstack将这些值放回原始顺序。


2

使用dplyr的一种选项,通过按原始向量分组后取相邻序列元素的差异来实现。

library(dplyr)
tibble(v1) %>% 
   mutate(ind = row_number()) %>%
   group_by(v1) %>% 
   mutate(new = ind - lag(ind)) %>%
   pull(new)
#[1] NA NA  2 NA  2  4  1  4  1  3  1  7  1  1  6  1  1  1  8  6

数据

v1 <- c("A", "C", "A", "B", "A", "C", "C", "B", "B", "C", "C", "A", 
"A", "A", "B", "B", "B", "B", "C", "A")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接