在R

时间:2015-07-30 21:28:50

标签: r

我正在尝试将具有分类数据(“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。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

@nongkrong是对的 - 阅读?formulas,您会看到大多数接受formula作为输入的函数(例如lmglm等)会自动将分类变量(存储为factorcharacter 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相等;结果将是TRUEFALSE(如果缺少值,则为NA)。乘以1*1)会强制输出为整数(因此TRUE变为1FALSE变为0)。

lapply将第二个参数中的函数应用于第一个参数的每个元素 - 因此对于levels(d$purpose)的每个元素(即d$purpose的每个级别),我们输出一个01 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 = "+"))]