You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:25:39