更新:对于那些回复的人道歉,在我最初的例子中,我忽略了作为一个因素data.frame()创建的事实,var而不是像我想象的那样作为一个角色向量.我已经纠正了这个例子,这将至少打破其中一个答案.
- 原版的 -
我有一个数据框,我正在执行一系列dplyr和tidyr操作,我想为指标变量添加列,编码为0或1,并在dplyr链中执行此操作.因子的每个级别(当前存储为字符向量)应该在单独的列中编码,并且列名称是固定前缀与变量级别的串联,例如var具有级别a,新列var_a将是1,以及所有其他级别行将为var_a0.
下面使用基数R的最小例子产生了我想要的结果(感谢这篇博文),但我想将它全部卷入dplyr链,并且无法弄清楚如何做到这一点.
library(dplyr)
df <- data.frame(var = sample(x = letters[1:4], size = 10, replace = TRUE), stringsAsFactors = FALSE)
for(level in unique(df$var)){
df[paste("var", level, sep = "_")] <- ifelse(df$var == level, 1, 0)
}
Run Code Online (Sandbox Code Playgroud)
请注意,实际数据集包含多个列,创建指示符变量时不应更改或删除任何列,但列var可以转换为类型因子.
它不漂亮,但这个功能应该有效
dummy <- function(data, col) {
for(c in col) {
idx <- which(names(data)==c)
v <- data[[idx]]
stopifnot(class(v)=="factor")
m <- matrix(0, nrow=nrow(data), ncol=nlevels(v))
m[cbind(seq_along(v), as.integer(v))]<-1
colnames(m) <- paste(c, levels(v), sep="_")
r <- data.frame(m)
if ( idx>1 ) {
r <- cbind(data[1:(idx-1)],r)
}
if ( idx<ncol(data) ) {
r <- cbind(r, data[(idx+1):ncol(data)])
}
data <- r
}
data
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例data.frame
dd <- data.frame(a=runif(30),
b=sample(letters[1:3],30,replace=T),
c=rnorm(30),
d=sample(letters[10:13],30,replace=T)
)
Run Code Online (Sandbox Code Playgroud)
并指定要作为字符向量展开的列.你可以做
dd %>% dummy("b")
Run Code Online (Sandbox Code Playgroud)
要么
dd %>% dummy(c("b","d"))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2945 次 |
| 最近记录: |