#r #function #vector #duplicates
#r #функция #вектор #дубликаты
Вопрос:
Я пытаюсь написать функцию, которая принимает вектор и подмножествует его в соответствии с несколькими шагами:
- Отбрасывает любые нежелательные значения
- Удаляет дубликаты.
- Возвращает индексы исходного вектора после учета шагов (1) и (2).
Например, при наличии следующего входного вектора:
vec_animals lt;- c("dog", "dog", "dog", "dog", "cat", "dolphin", "dolphin")
и
throw_away_val lt;- "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 lt;- c(2003, 2003, 2003, 2007, 2007, 2011, 2011, 2011) throw_away_val lt;- 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 lt;- function(x, throw_away) { which(x != throw_away) }
который затем возвращает индексы оригинала vec_animals
, такие как:
get_index(vec_animals, "cat") #gt; [1] 1 2 3 4 6 7
Если мы используем этот вывод для подмножества vec_animal
, мы получим:
vec_animals[get_index(vec_animals, "cat")] #gt; [1] "dog" "dog" "dog" "dog" "dolphin" "dolphin"
Вы могли бы предложить оперировать этим выводом, например:
vec_animals[get_index(vec_animals, "cat")] |gt; unique() #gt; [1] "dog" "dolphin"
Но нет, мне нужно get_index()
сразу же вернуть правильные индексы (в данном случае 1
и 6
).
Редактировать
Соответствующая процедура, в которой мы можем получить индексы первых появлений дубликатов, снабжена
library(bit64) vec_num lt;- as.integer64(c(4, 2, 2, 3, 3, 3, 3, 100, 100)) unipos(vec_num) #gt; [1] 1 2 4 8
Или в более общем плане
which(!duplicated(vec_num)) #gt; [1] 1 2 4 8
Такие решения были бы великолепны, если бы не нужно было также выбрасывать ненужные ценности.
Ответ №1:
Попробуй:
get_index lt;- function(x, throw_away) { which(!duplicated(x) amp; x!=throw_away) } gt; get_index(vec_animals, "cat") [1] 1 6
Комментарии:
1. Спасибо. вы можете изменить значение
x!=throw_away
на!(x %in% throw_away)
, если хотите отказаться от более чем одного значения2. Было бы неплохо (хотя и не обязательно), если бы вы могли подробнее рассказать о механизме, по которому работает ваше решение. Я понимаю, что это связано с
R
векторизованными операциями, но у меня нет большой интуиции, кроме этого.3. Посмотрите, как работают отдельные компоненты.
duplicated(x)
задает вектор логических значений, соответствующий тому, является ли каждый из элементовx
дубликатом предыдущего значения или нет.x!=throwaway
также является вектором логических значений, соответствующим тому, следует ли выбрасывать каждый элемент.which
затем возвращает индексы элементовx
, которые удовлетворяют обоим условиям (т. е. оба вектора являютсяTRUE
).4. Значит, первое
!
отрицает всеamp;
выражение целиком? Или это только отрицаетduplicates(x)
?5. Первое
!
только отрицаетduplicated(x)
. Я мог бы использовать скобки, чтобы сделать это более ясным.
Ответ №2:
Вот простая функция, написанная самостоятельно, которая предоставляет необходимую информацию.
vec_animals lt;- c("dog", "dog", "dog", "dog", "cat", "dolphin", "dolphin") get_indexes lt;- function(x, throw_away){ elements lt;- (unique(x))[(unique(x)) != throw_away] index lt;- lapply(1:length(elements), function(i) {which(x %in% elements[i]) }) index2return lt;- c() for (j in 1:length(index)) { index2return lt;- c(index2return, min(index[[j]])) } return(index2return) } get_indexes(x = vec_animals, throw_away = "cat") [1] 1 6
Ответ №3:
Мой подход :
vec_animals lt;- c("dog", "dog", "dog", "dog", "cat", "dolphin", "dolphin") throw_away_val lt;- "cat" my_function lt;- function(x, y) { my_df lt;- data.frame("Origin" = x, "Position" = seq.int(from = 1, to = length(x), by = 1), stringsAsFactors = FALSE) my_var lt;- which(my_df$Origin %in% y) if (length(my_var)) { my_df lt;- my_df[-my_var,] } my_df lt;- my_df[!duplicated(my_df$Origin),] return (my_df) } my_df lt;- my_function(vec_animals, throw_away_val)