Допустим, у меня есть этот набор данных
> example <- data.frame(a = 1:10, b = 10:1, c = 1:5 )
Я хочу создать новую переменную d. Я хочу, чтобы в d значение 1, когда хотя бы в одной из переменных a b c присутствует значение 1 2 или 3.
d должен выглядеть так:
d <- c(1, 1, 1, 0, 0, 1, 1, 1, 1, 1)
Заранее спасибо.





Вы можете сделать это с помощью apply (хотя и немного медленно)
Логика: any будет сравнивать, присутствуют ли какие-либо 1,2 или 3 или нет, apply используется для повторения этой логики в каждой из строк. Затем, наконец, преобразование логического результата в числовое, добавив +0 (вы можете выбрать здесь as.numeric, если хотите быть более выразительным)
d <- apply(example,1 ,function(x)any(x==1|x==2|x==3))+0
Если кто-то хочет ограничить столбцы или запустить логику для некоторых столбцов, то это также можно сделать:
d <- apply(example[,c("a","b","c")], 1, function(x)any(x==1|x==2|x==3))+0
Здесь у вас есть контроль над столбцами, которые следует принимать или игнорировать в зависимости от ваших потребностей.
Выход:
> d
[1] 1 1 1 0 0 1 1 1 1 1
@AmelioTornincasa, Да, это будет повторяться для каждой переменной, присутствующей в вашем data.frame
Вы можете использовать rowSums, чтобы получить логический вектор 1, 2 or 3, появляющийся в каждой строке, и обернуть его в as.integer для преобразования в 0 и 1, т.е.
as.integer(rowSums(df == 1|df == 2| df == 3) > 0)
#[1] 1 1 1 0 0 1 1 1 1 1
Попробуйте этот метод, проверьте, есть ли в каком-либо столбце один элемент в списке x.
x<-c(1,2,3)
example$d<-as.numeric(example$a %in% x | example$b %in% x | example$c %in% x)
example
a b c d
1 1 10 1 1
2 2 9 2 1
3 3 8 3 1
4 4 7 4 0
5 5 6 5 0
6 6 5 1 1
7 7 4 2 1
8 8 3 3 1
9 9 2 4 1
10 10 1 5 1
Это то, что я искал. Спасибо :)
Это лучший ответ - простой, быстрый, понятный код. Не уверен, почему он был отклонен. Использование apply, dplyr и т. д. Здесь излишне. Если бы у вас было 10 столбцов, все могло бы быть иначе.
Спасибо @ dash2. Все остальные ответы работают хорошо, но в моем случае спрашивающий может также найти вывод, интегрированный в его исходный data.frame, и я полагаю, что это то, что он хочет.
Будет работать с любым количеством варов:
example <- data.frame(a = 1:10, b = 10:1, c = 1:5 )
x <- c(1, 2, 3)
as.integer(Reduce(function(a, b) (a %in% x) | (b %in% x), example))
Две другие возможности, которые работают с любым количеством столбцов:
#option 1
example$d <- +(rowSums(sapply(example, `%in%`, 1:3)) > 0)
#option 2
library(matrixStats)
example$d <- rowMaxs(+(sapply(example, `%in%`, 1:3)))
которые оба дают:
> example a b c d 1 1 10 1 1 2 2 9 2 1 3 3 8 3 1 4 4 7 4 0 5 5 6 5 0 6 6 5 1 1 7 7 4 2 1 8 8 3 3 1 9 9 2 4 1 10 10 1 5 1
В пакете dplyr:
library(dplyr)
x <- 1:3
example %>% mutate(d = as.integer(a %in% x | b %in% x | c %in% x))
общее решение:
example %>%
sapply(function(i)i %in% x) %>% apply(1,any) %>% as.integer
#[1] 1 1 1 0 0 1 1 1 1 1
Спасибо за быстрый ответ. Что, если бы у меня была 4-я переменная, но мне все равно, что там. При "любых" значениях 1,2,3 в четвертой переменной также будут учитываться ....