从分类variables中创build新的虚拟variables列
我有几个数据集,有75,000个观察值,一个type
variables可以取值0-4。 我想为所有types的每个数据集添加五个新的虚拟variables。 我可以想出这样做的最佳方式如下:
# 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")
虽然这个工作,它是非常慢(合并function甚至崩溃了几次)。 有没有更有效的方法来做到这一点? 也许这个function是我不熟悉的包的一部分?
R有一个“子语言”将公式转换成devisematrix,并且可以利用语言的精神。 它快速简洁。 例如:你有一个基数预测器x,一个分类预测器catVar和一个响应y。
> binom <- data.frame(y=runif(1e5), x=runif(1e5), catVar=as.factor(sample(0:4,1e5,TRUE))) > head(binom) yx 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
如果你打算使用data.table包, mltools有一个one_hot()方法。
library(data.table) library(mltools) binom <- data.table(y=runif(1e5), x=runif(1e5), catVar=as.factor(sample(0:4,1e5,TRUE))) one_hot(binom) yx catVar_0 catVar_1 catVar_2 catVar_3 catVar_4 1: 0.90511891 0.83045050 0 0 1 0 0 2: 0.91375984 0.73273830 0 0 0 1 0 3: 0.01926608 0.10301409 0 0 1 0 0 4: 0.48691138 0.24428157 0 1 0 0 0 5: 0.60660396 0.09132816 0 0 1 0 0 --- 99996: 0.12908356 0.26157731 0 1 0 0 0 99997: 0.96397273 0.98959000 0 1 0 0 0 99998: 0.16818414 0.37460941 1 0 0 0 0 99999: 0.72610508 0.72055867 1 0 0 0 0 100000: 0.89710998 0.24155507 0 0 0 0 1
ifelse
是向量化的,所以如果我正确地理解你的代码,你不需要那个sapply
。 而我不会使用合并 – 我会使用SQLite或PostgreSQL。
一些示例数据也可以帮助:-)