Создать новый вектор на основе условий из другого вектора

Имею вектор v1 = c(0, 3, 5, 1, 1, 1, 3, 5, 0). Как я могу создать вектор равной длины, НО со значениями -1, если 0 или 3, и 1, если 1 или 5.

Итак, с v1 = c(0, 3, 5, 1, 1, 3, 5, 0) я ожидаю новый вектор:

v2 = c(-1, -1, 1, 1, 1, -1, 1, -1)

В первой v1 у вас больше единиц? опечатка?

zx8754 09.04.2018 12:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
5 668
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

В ожидаемом выходе отсутствует одно значение, поскольку его длина меньше длины входного вектора.

v1 = c(0, 3, 5, 1, 1, 1, 3, 5, 0)

v2 <- ifelse(v1 == 0 | v1 == 3, -1, ifelse(v1 == 1 | v1 == 5, 1, v1))

your_result <- c(-1, -1,  1,  1,  1,  1, -1,  1, -1)
identical(v2, your_result)
[1] TRUE
 v1 = c(0, 3, 5, 1, 1, 3, 5, 0)
 v2 <- ifelse(v1 == 0 | v1 == 3, -1, 1)
 v2
 # [1] -1 -1  1  1  1 -1  1 -1

Альтернатива I для заполнения пустого вектора (с использованием функции vector()) по условию (функция ifelse())

v1 = c(0, 3, 5, 1, 1, 3, 5, 0)
v1
# [1] 0 3 5 1 1 3 5 0

## Empty Numeric vector of length v1  
Vec <- vector("numeric",length = length(v1))
Vec
# [1] 0 0 0 0 0 0 0 0

## Filling for 0 or 3
Vec[] <- ifelse(v1 == 0 | v1 == 3, -1, v1)
Vec
# [1] -1 -1  5  1  1 -1  5 -1

## Filling for 1 or 5
Vec[] <- ifelse(v1 == 1 | v1 == 5, 1, Vec)
Vec
# [1] -1 -1  1  1  1 -1  1 -1

Альтернатива II с использованием %in% вместе с vector() и ifelse() для заполнения пустого вектора

v1 = c(0, 3, 5, 1, 1, 3, 5, 0)
v1
# [1] 0 3 5 1 1 3 5 0

Result <- vector("numeric",length = length(v1))
Result
# [1] 0 0 0 0 0 0 0 0

Result[] <- ifelse(v1 %in% c(0,3), -1, v1)
Result
# [1] -1 -1  5  1  1 -1  5 -1

Result[] <- ifelse(Result %in% c(1,5), 1, Result)
Result
# [1] -1 -1  1  1  1 -1  1 -1

это решение не учитывает второе условие

Seymour 09.04.2018 11:31

Так как условий всего два, он вам не понадобится. Несмотря на то, что альтернатива также была предоставлена ​​путем заполнения пустого векторного условия.

Sowmya S. Manian 09.04.2018 11:34

Я предполагаю, что вы совершенно новичок в R. Для этого вы можете просто создать вектор v2, который полностью состоит из 0, и использовать простые логические операторы для остальных. Как таковой:

v1 <- c(0, 3, 5, 1, 1, 1, 3, 5, 0)
#this creates a vector in which 0 is repeated length(v1) times
v2 <- rep(0,length(v1)) 

v2[v1 == 1 | v2 == 5] <- 1
v2[v1 == 0 | v2 == 3] <- -1    

почему вы создаете вектор, полный нулей, а не просто определяете его как v2 <- v1?

Seymour 09.04.2018 11:33

@Seymour старые глупые привычки

iliupersis 09.04.2018 17:35
Ответ принят как подходящий

Другая возможность:

v2 <- c(-1,1)[1 + (v1 %in% c(1,5))]

который дает:

> v2
[1] -1 -1  1  1  1 -1  1 -1

Что это значит:

  • v1 %in% c(1,5) создает логический вектор
  • добавляя 1, вы создаете целочисленный вектор 1 и 2.
  • вы можете использовать это как вектор индекса на c(-1,1), который создаст требуемый результат

Если v1 содержит номера, отличные от 0, 1, 3 или 5, вы должны быть более точными:

v2 <- c(-1,1)[(v1 %in% c(0,3)) + 2*(v1 %in% c(1,5))]

Я вижу много хороших ответов, добавлю еще один программный подход.

v1 <- c(0, 3, 5, 1, 1, 1, 3, 5, 0)
v2 <- integer(length(v1))

for (i in 1:length(v1)){
  # if val is equal to 0 or 3 new value is set to -1
  if (v1[i] == 0 | v1[i] == 3){
    new_val <- -1
  }
  # if val is equal to 1 or 5 new value is set to 1
  else if (v1[i] == 1 | v1[i] == 5 ){
    new_val <- 1
  }
  # else the value remains the same
  else{
    new_val <- v1[i]
  }
  v2[i] <- new_val 
}
v2
# -1 -1  1  1  1  1 -1  1 -1

Это меньше похоже на «программирование», потому что любой хороший программист знает, что вы не растите вектор в цикле.

Roland 09.04.2018 12:13

Думаю, моя питоновая природа взяла лучшее от меня здесь. Я понимаю, что вектор копируется все время, и это может быть медленным для больших наборов данных. Однако это небольшой пример, и он отлично работает. С большим количеством программирования, как я, имел в виду, что это более полно написано. Таким образом, задавший вопрос может получить дополнительные знания о возможностях R. Так что я надеюсь, что в будущем вы сможете оставить этот ядовитый комментарий при себе. Сообщество stackoverflow уже достаточно токсично.

candah 09.04.2018 13:02

Цикл for - это не то, что вам следует использовать в R для этого, хотя он был бы предпочтительным инструментом для более низкоуровневых языков программирования. Таким образом, я предполагаю, что вы показываете это только в дидактических целях. Однако, если это действительно так, вы, конечно, должны продемонстрировать хорошие практики программирования, предварительно выделив вектор и назначив ему, что легко сделать в R и что вы бы сделали и на других (более низкоуровневых) языках программирования. Нет оправдания распространению плохой практики.

Roland 09.04.2018 13:18

Сменил ответ на более эффективное решение R. Я сейчас прячусь. Надеюсь, Роланд меня не найдет: s

candah 09.04.2018 13:53

вы также можете попробовать решение tidyverse.

library(tidyverse)
mutate(tibble(a=c(0, 3, 5, 1, 1, 1, 3, 5, 0)),
              b=case_when(a %in% c(0,3) ~ -1,
                          a %in% c(1,5) ~ 1))
# A tibble: 9 x 2
      a     b
  <dbl> <dbl>
1    0.   -1.
2    3.   -1.
3    5.    1.
4    1.    1.
5    1.    1.
6    1.    1.
7    3.   -1.
8    5.    1.
9    0.   -1.

добавление pull дает вам вектор

.Last.value %>% pull(b)
[1] -1 -1  1  1  1  1 -1  1 -1

В пакете машина есть функция recode():

library("car")
v1 = c(0, 3, 5, 1, 1, 3, 5, 0)
# v2 = c(-1, -1, 1, 1, 1, -1, 1, -1)
recode(v1, "c(0, 3)=-1; else=1")
# [1] -1 -1  1  1  1 -1  1 -1

или (если вы хотите установить NA для значений, которых нет в c(0, 1, 3, 5)):

recode(v1, "c(0, 3)=-1; c(1, 5)=1; else=NA")

Другие вопросы по теме