Создать фиктивный столбец на основе других столбцов
Допустим, у меня есть этот набор данных
> 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)
Заранее спасибо.
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
Вы можете сделать это с помощью 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
Две другие возможности, которые работают с любым количеством столбцов:
#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
Будет работать для любого количества переменных:
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))
С 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
Попробуйте этот метод, проверьте, есть ли в каком-либо столбце в списке один элемент, присутствующий в 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