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

Допустим, у меня есть этот набор данных

> 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)

Заранее спасибо.


person Community    schedule 27.04.2018    source источник


Ответы (7)


Вы можете использовать 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
person Sotos    schedule 27.04.2018

Будет работать с любым количеством варов:

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))
person r.user.05apr    schedule 27.04.2018

В пакете dplyr:

library(dplyr)
x <- 1:3
example %>% mutate(d = as.integer(a %in% x | b %in% x | c %in% x))
person hpesoj626    schedule 27.04.2018

Две другие возможности, которые работают с любым количеством столбцов:

#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
person Jaap    schedule 27.04.2018

Вы можете сделать это с помощью 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
person PKumar    schedule 27.04.2018
comment
Спасибо за быстрый ответ. Что, если бы у меня была 4-я переменная, но мне все равно, что там. При любых значениях 1,2,3 в четвертой переменной также будет учитываться .... - person ; 27.04.2018
comment
@AmelioTornincasa, Да, это будет повторяться для каждой переменной, присутствующей в вашем data.frame - person PKumar; 27.04.2018

общее решение:

example %>%
sapply(function(i)i %in% x) %>% apply(1,any) %>% as.integer
#[1] 1 1 1 0 0 1 1 1 1 1
person Andre Elrico    schedule 27.04.2018

Попробуйте этот метод, проверьте, есть ли в каком-либо столбце один элемент, присутствующий в 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
person Terru_theTerror    schedule 27.04.2018
comment
Это то, что я искал. Спасибо :) - person ; 27.04.2018
comment
Это лучший ответ - простой, быстрый, понятный код. Не уверен, почему это было отклонено. Использование apply, dplyr и т. Д. Здесь излишне. Если бы у вас было 10 столбцов, все могло бы быть иначе. - person ; 27.04.2018
comment
Спасибо @ dash2. Все остальные ответы работают хорошо, но в моем случае спрашивающий также может найти вывод, интегрированный в его исходный data.frame, и я полагаю, что это то, что он хочет. - person Terru_theTerror; 27.04.2018