У меня есть несколько наборы данных с 75 000 наблюдений и a type
переменная, которая может взять значение 0-4. Я хочу добавить пять новых фиктивных переменных к каждому набору данных для всех типов. Лучшим способом я мог придумать, чтобы сделать, это следующие:
# For the 'binom' data set create dummy variables for all types in all data sets
binom.dummy.list<-list()
for(i in 0:4){
binom.dummy.list[[i+1]]<-sapply(binom$type,function(t) ifelse(t==i,1,0))
}
# Add and merge data
binom.dummy.df<-as.data.frame(do.call("cbind",binom.dummy.list))
binom.dummy.df<-transform(binom.dummy.df,id=1:nrow(binom))
binom<-merge(binom,binom.dummy.df,by="id")
В то время как это работает, это невероятно медленно (функция слияния даже отказала несколько раз). Существует ли более эффективный способ сделать это? Возможно, эта функциональность является частью пакета, с которым я не знаком?
R имеет «подъязык» для перевода формул в матрицу дизайна и в дух языка, вы можете воспользоваться этим. Это быстро и лаконично. Пример: у вас есть кардинальный предиктор x, категориальный предиктор catVar и ответ y.
> binom <- data.frame(y=runif(1e5), x=runif(1e5), catVar=as.factor(sample(0:4,1e5,TRUE)))
> head(binom)
y x catVar
1 0.5051653 0.34888390 2
2 0.4868774 0.85005067 2
3 0.3324482 0.58467798 2
4 0.2966733 0.05510749 3
5 0.5695851 0.96237936 1
6 0.8358417 0.06367418 2
Просто сделай
> A <- model.matrix(y ~ x + catVar,binom)
> head(A)
(Intercept) x catVar1 catVar2 catVar3 catVar4
1 1 0.34888390 0 1 0 0
2 1 0.85005067 0 1 0 0
3 1 0.58467798 0 1 0 0
4 1 0.05510749 0 0 1 0
5 1 0.96237936 1 0 0 0
6 1 0.06367418 0 1 0 0
Готово.
Дрю, это намного быстрее и не должно вызывать сбоев.
> binom <- data.frame(data=runif(1e5),type=sample(0:4,1e5,TRUE))
> for(t in unique(binom$type)) {
+ binom[paste("type",t,sep="")] <- ifelse(binom$type==t,1,0)
+ }
> head(binom)
data type type2 type4 type1 type3 type0
1 0.11787309 2 1 0 0 0 0
2 0.11884046 4 0 1 0 0 0
3 0.92234950 4 0 1 0 0 0
4 0.44759259 1 0 0 1 0 0
5 0.01669651 2 1 0 0 0 0
6 0.33966184 3 0 0 0 1 0
А как насчет использования model.matrix ()?
> binom <- data.frame(data=runif(1e5),type=sample(0:4,1e5,TRUE))
> head(binom)
data type
1 0.1412164 2
2 0.8764588 2
3 0.5559061 4
4 0.3890109 3
5 0.8725753 3
6 0.8358100 1
> inds <- model.matrix(~ factor(binom$type) - 1)
> head(inds)
factor(binom$type)0 factor(binom$type)1 factor(binom$type)2 factor(binom$type)3 factor(binom$type)4
1 0 0 1 0 0
2 0 0 1 0 0
3 0 0 0 0 1
4 0 0 0 1 0
5 0 0 0 1 0
6 0 1 0 0 0
ifelse
векторизован, поэтому, если я правильно понял ваш код, вам не нужен этот sapply
. И я бы не стал использовать merge - я бы использовал SQLite или PostgreSQL.
Некоторые примеры данных тоже бы помогли :-)