R中dummyVars()生成哑变量时列名异常问题求助
问题根源解析:caret::dummyVars分隔符失效与特殊字符被替换的原因
我用caret包的dummyVars()函数生成N水平哑变量,明明设置了sep="-"参数,但生成的列名既没用到指定的分隔符,<、>这类符号还被替换成了点号。后来在data.frame()里加了check.names=FALSE参数才解决,想知道问题出在哪。
错误代码及运行结果
df <- data.frame(fruit=as.factor(c("apple", "orange","orange", "carrot", "apple")), st=as.factor(c("CA", "MN","MN", "NY", "NJ")), wt=as.factor(c("<2","2-4",">4","2-4","<2")), buy=c(1,1,0,1,0)) # 原始数据集 # fruit st wt buy # 1 apple CA <2 1 # 2 orange MN 2-4 1 # 3 orange MN >4 0 # 4 carrot NY 2-4 1 # 5 apple NJ <2 0 library(caret) dmy <- dummyVars(buy~ ., data = df, sep="-") df2 <- data.frame(predict(dmy, newdata = df)) df2 # fruit.apple fruit.carrot fruit.orange st.CA st.MN st.NJ st.NY wt..2 wt..4 wt.2.4 # 1 1 0 0 1 0 0 0 1 0 0 # 2 0 0 1 0 1 0 0 0 0 1 # 3 0 0 1 0 1 0 0 0 1 0 # 4 0 1 0 0 0 0 1 0 0 1 # 5 1 0 0 0 0 1 0 1 0 0
解决后代码及运行结果
df2 <- data.frame(predict(dmy, newdata = df), check.names = FALSE) df2 # fruit-apple fruit-carrot fruit-orange st-CA st-MN st-NJ st-NY wt-<2 wt->4 wt-2-4 # 1 1 0 0 1 0 0 0 1 0 0 # 2 0 0 1 0 1 0 0 0 0 1 # 3 0 0 1 0 1 0 0 0 1 0 # 4 0 1 0 0 0 0 1 0 0 1 # 5 1 0 0 0 0 1 0 1 0 0
问题根源
问题不在dummyVars()函数上,而是data.frame()的默认行为导致的:
data.frame()默认开启check.names=TRUE,这个参数会强制把列名转换成R认可的合法变量名。- R的合法变量名规则是:只能以字母、点号或下划线开头,不能包含
<、>、-这类特殊字符,也不能和内置函数重名。 - 所以当
predict(dmy)返回的结果已经用sep="-"生成了fruit-apple、wt-<2这类列名时,data.frame()会自动把-替换成.,把<、>也替换成.,就出现了你看到的fruit.apple、wt..2这种列名。 - 加上
check.names=FALSE后,会关闭这个自动检查和转换,保留dummyVars()生成的原始列名,自然就符合你的要求了。
内容的提问来源于stack exchange,提问作者Mathica
相关产品推荐
相关产品推荐

