我正在尝试将具有分类数据(“A”,“B”或“C”)的列转换为3列,其中1,0,0将为“A”; 0,1,0代表'B'等。
我在网上找到了这个代码:
flags = data.frame(Reduce(cbind,
lapply(levels(d$purpose), function(x){(d$purpose == x)*1})
))
names(flags) = levels(d$purpose)
d = cbind(d, flags)
# Include the new columns as input variables
levelnames = paste(names(flags), collapse = " + ")
neuralnet(paste("output ~ ", levelnames), d)
Converting categorical variables in R for ANN (neuralnet)
但是我对R来说很新。任何人都可以分解这些看似复杂的代码吗?
编辑:
实施@nongkrong的建议我遇到了一个问题:
CSV:
X1,X2,X3
A,D,Q
B,E,R
C,F,S
B,G,T
C,H,U
A,D,Q
R:
newData <- read.csv("new.csv")
newerData <- model.matrix(~ X1 + X2 + X3 -1, data=newData)
newerData
R输出:
X1A X1B X1C X2E X2F X2G X2H X3R X3S X3T X3U
1 1 0 0 0 0 0 0 0 0 0 0
2 0 1 0 1 0 0 0 1 0 0 0
3 0 0 1 0 1 0 0 0 1 0 0
4 0 1 0 0 0 1 0 0 0 1 0
5 0 0 1 0 0 0 1 0 0 0 1
6 1 0 0 0 0 0 0 0 0 0 0
它适用于1列,但缺少X2D和X3Q。有什么想法吗?
答案 0 :(得分:2)
@nongkrong是对的 - 阅读?formulas
,您会看到大多数接受formula
作为输入的函数(例如lm
,glm
等)会自动将分类变量(存储为factor
或character
s)转换为虚拟变量;您可以通过在公式中指定factor
来强制执行非as.factor(var)
数字变量。
那就是说,我遇到过手动创建这些指标很方便的情况 - 例如,一个种族变量的数据集,其中<1%的数据适合一个或几个种族代码。还有其他方法可以解决这个问题(例如,删除少数族裔观察,例如),但我发现情况因情况而异。
所以,我已经为你注释了代码:
flags = data.frame(Reduce(cbind,
lapply(levels(d$purpose), function(x){(d$purpose == x)*1})
))
在第一行中进行了很多,所以让我们一点一点地进行:
d$purpose==x
检查d$purpose
的每个条目是否与x
相等;结果将是TRUE
或FALSE
(如果缺少值,则为NA
)。乘以1
(*1
)会强制输出为整数(因此TRUE
变为1
而FALSE
变为0
)。
lapply
将第二个参数中的函数应用于第一个参数的每个元素 - 因此对于levels(d$purpose)
的每个元素(即d$purpose
的每个级别),我们输出一个0
和1
s的向量,其中1
s对应于与给定级别匹配的d$purpose
元素。 lapply
的输出为list
(因此在应用前为l
),其中一个列表元素对应于d$purpose
的每个级别。
我们希望将其转换为data.frame
,因此list
不是很有用;我们使用Reduce
将信息从list
退回到data.frame
表单。 Reduce(cbind,LIST)
与cbind(LIST[[1]],LIST[[2]],LIST[[3]],...)
相同 - 方便的简写,尤其是当我们不知道LIST
的长度时。
将其包含在data.frame
中,将其转换为模式data.frame
。
#This line simply puts column names on each of the indicator variables
# Note that you can replace the RHS of this line with whatever
# naming convention you want for the levels--a common approach might
# be to specify paste0(levels(d$purpose),"_flag"), e.g.
names(flags) = levels(d$purpose)
#this line adds all the indicator variables to the original
# data.frame
d = cbind(d, flags)
#this creates a string of the form "level1 + level2 + ... + leveln"
levelnames = paste(names(flags), collapse = " + ")
#finally we create a formula of the form y~x+d1+d2+d3
# where each of the d* is a dummy for a level of the categorical variable
neuralnet(paste("output ~ ", levelnames), d)
另请注意,在data.table
包中可以更简单地完成这样的事情:
library(data.table)
setDT(d)
l = levels(purpose)
d[ , (l) := lapply(l, function(x) as.integer(purpose == x))]
d[ , neuralnet(paste0("output~", paste0(l, collapse = "+"))]