Имею вектор 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 = 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
это решение не учитывает второе условие
Так как условий всего два, он вам не понадобится. Несмотря на то, что альтернатива также была предоставлена путем заполнения пустого векторного условия.
Я предполагаю, что вы совершенно новичок в 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 старые глупые привычки
Другая возможность:
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
Это меньше похоже на «программирование», потому что любой хороший программист знает, что вы не растите вектор в цикле.
Думаю, моя питоновая природа взяла лучшее от меня здесь. Я понимаю, что вектор копируется все время, и это может быть медленным для больших наборов данных. Однако это небольшой пример, и он отлично работает. С большим количеством программирования, как я, имел в виду, что это более полно написано. Таким образом, задавший вопрос может получить дополнительные знания о возможностях R. Так что я надеюсь, что в будущем вы сможете оставить этот ядовитый комментарий при себе. Сообщество stackoverflow уже достаточно токсично.
Цикл for - это не то, что вам следует использовать в R для этого, хотя он был бы предпочтительным инструментом для более низкоуровневых языков программирования. Таким образом, я предполагаю, что вы показываете это только в дидактических целях. Однако, если это действительно так, вы, конечно, должны продемонстрировать хорошие практики программирования, предварительно выделив вектор и назначив ему, что легко сделать в R и что вы бы сделали и на других (более низкоуровневых) языках программирования. Нет оправдания распространению плохой практики.
Сменил ответ на более эффективное решение R. Я сейчас прячусь. Надеюсь, Роланд меня не найдет: s
вы также можете попробовать решение 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")
В первой v1 у вас больше единиц? опечатка?