编写一个将向量作为输入的函数,丢弃不需要的值,去重,并返回原始向量的相应索引

Posted

技术标签:

【中文标题】编写一个将向量作为输入的函数,丢弃不需要的值,去重,并返回原始向量的相应索引【英文标题】:Writing a function that takes a vector as input, throws away unwanted values, de-duplicates, and returns respective indexes of original vector 【发布时间】:2022-01-13 06:58:00 【问题描述】:

我正在尝试编写一个函数,它接收一个向量并根据几个步骤对其进行子集化:

    丢弃任何不需要的值 删除重复项。 在考虑步骤 (1) 和 (2) 后返回原始向量的 索引

例如,提供以下输入向量:

vec_animals <- c("dog", "dog", "dog", "dog", "cat", "dolphin", "dolphin")

throw_away_val <- "cat"

我希望我的函数 get_indexes(x = vec_animals, y = throw_away_val) 返回:

# [1] 1 6   # `1` is the index of the 1st unique ("dog") in `vec_animals`, `6` is the index of the 2nd unique ("dolphin")

另一个例子

vec_years <- c(2003, 2003, 2003, 2007, 2007, 2011, 2011, 2011)
throw_away_val <- 2003

返回:

# [1] 4 6 # `4` is the position of 1st unique (`2007`) after throwing away unwanted val; `6` is the position of 2nd unique (`2011`).

我的初步尝试

以下函数返回索引但不考虑重复项

get_index <- function(x, throw_away) 
  which(x != throw_away)

然后返回原始vec_animals 的索引,例如:

get_index(vec_animals, "cat")
#> [1] 1 2 3 4 6 7

如果我们将此输出用于子集vec_animal,我们会得到:

vec_animals[get_index(vec_animals, "cat")]
#> [1] "dog"     "dog"     "dog"     "dog"     "dolphin" "dolphin"

您可以建议对此输出进行操作,例如:

vec_animals[get_index(vec_animals, "cat")] |> unique()
#> [1] "dog"     "dolphin"

但不,我需要 get_index() 立即返回正确的索引(在本例中为 16)。


编辑


提供了一个相关程序,我们可以在其中获取第一次出现重复的索引

library(bit64)

vec_num <- as.integer64(c(4, 2, 2, 3, 3, 3, 3, 100, 100))
unipos(vec_num)
#> [1] 1 2 4 8

或者更一般的

which(!duplicated(vec_num))
#> [1] 1 2 4 8

如果不需要同时丢弃不需要的值,这样的解决方案会很棒。

【问题讨论】:

【参考方案1】:

试试:

get_index <- function(x, throw_away) 
  which(!duplicated(x) & x!=throw_away)
  

> get_index(vec_animals, "cat")
[1] 1 6

【讨论】:

谢谢。如果您想丢弃多个值,可以将 x!=throw_away 更改为 !(x %in% throw_away) 如果您能详细说明解决方案起作用的机制,那就太好了(尽管不是必需的)。我知道这与R 的矢量化操作有关,但除此之外没有太多直觉。 查看各个组件的工作方式。 duplicated(x) 给出了一个布尔向量,对应于 x 的每个元素是否是先前值的副本。 x!=throwaway 也是一个布尔向量,对应于每个元素是否要被丢弃。 which 然后返回满足两个条件的x 元素的索引(即两个向量都是TRUE)。 所以第一个! 否定了整个&amp; 表达式?还是只否定duplicates(x) 第一个! 只否定duplicated(x)。我本可以使用括号来更清楚地说明这一点。【参考方案2】:

这是一个提供所需信息的简单自写函数。

vec_animals <- c("dog", "dog", "dog", "dog", "cat", "dolphin", "dolphin")

get_indexes <- function(x, throw_away)
  elements <- (unique(x))[(unique(x)) != throw_away]
  index <- lapply(1:length(elements), function(i) which(x %in% elements[i]) )
  index2return <- c()
  for (j in 1:length(index)) 
    index2return <- c(index2return, min(index[[j]]))
  
  return(index2return)


get_indexes(x = vec_animals, throw_away = "cat")
[1] 1 6

【讨论】:

【参考方案3】:

我的方法:

vec_animals <- c("dog", "dog", "dog", "dog", "cat", "dolphin", "dolphin")
throw_away_val <- "cat"

my_function <- function(x, y) 
my_df <- data.frame("Origin" = x,
                  "Position" = seq.int(from = 1, to = length(x), by = 1),
                  stringsAsFactors = FALSE)
my_var <- which(my_df$Origin %in% y)
if (length(my_var)) 
my_df <- my_df[-my_var,]

my_df <- my_df[!duplicated(my_df$Origin),]
return (my_df)


my_df <- my_function(vec_animals, throw_away_val)

【讨论】:

以上是关于编写一个将向量作为输入的函数,丢弃不需要的值,去重,并返回原始向量的相应索引的主要内容,如果未能解决你的问题,请参考以下文章

如何使用重复、while 循环或其他迭代技术编写一个根据某些规则返回输入向量索引的函数

直接将数组作为输入的一部分

布隆过滤器

使用向量作为矩阵的索引

如何为迭代器返回“null”值?

如何通过引用返回一个向量,隐含地期望一个空向量作为输入?