【问题标题】:How to construct a function for creating dummy variables?如何构造一个创建虚拟变量的函数?
【发布时间】:2020-11-22 12:37:58
【问题描述】:

我有一个数据框,它提供以下输出来创建虚拟变量。

library(dummies)
df1 <- data.frame(id = 1:4, year = 1991:1994)
df1 <- cbind(df1, dummy(df1$year, sep = "_"))
df1
#    id year df1_1991 df1_1992 df1_1993 df1_1994
#1  1 1991        1        0        0        0
#2  2 1992        0        1        0        0
#3  3 1993        0        0        1        0
#4  4 1994        0        0        0        1

我必须尝试创建一个函数式编程来实现相同的目标。

dummy_df <- function(dframe, x){
    dframe <- cbind(dframe, dummy(dframe$x, sep = "_"))
    return(dframe)
}

但是,当我运行输出时,我收到以下错误。

dummy_df(df1, year)
#Error in `[[.default`(x, 1) : subscript out of bounds

如何纠正这个错误并创建一个自动创建虚拟变量的函数?此外,如果该函数提供是否保留或丢弃正在分离以创建虚拟变量的初始列的选项会更好。例如,在上述数据框的情况下,应将保留或丢弃选项应用于列year

这个问题是在观察了一个类似的问题后发布的。 Pass a data.frame column name to a function

【问题讨论】:

  • 好的,我相信是我把上一个问题作为一个骗子关闭了。我会回答的。
  • @RuiBarradas 是的。也许你可以回答然后关闭它。
  • 不要关闭它,也许差异足以让它保持打开状态。

标签: r functional-programming data-manipulation dummy-variable


【解决方案1】:

问题是当year不带引号传递时,它是代表变量的符号,而不是字符串,是变量名。获取字符串的标准技巧是使用deparse(substitute(.))。然后提取器[[ 工作。

dummy_df <- function(dframe, x){
    x <- deparse(substitute(x))
    dframe <- cbind(dframe, dummy(dframe[[x]], sep = "_"))
    return(dframe)
}

dummy_df(df1, year)
#  id year df1_1991 df1_1992 df1_1993 df1_1994
#1  1 1991        1        0        0        0
#2  2 1992        0        1        0        0
#3  3 1993        0        0        1        0
#4  4 1994        0        0        0        1
#Warning message:
#In model.matrix.default(~x - 1, model.frame(~x - 1), contrasts = FALSE) :
#  non-list contrasts argument ignored

如果x 列可以被引用,则将上面的函数更改为as.character(substitute(.))。该函数将接受带引号和不带引号的x

dummy_df <- function(dframe, x){
    x <- as.character(substitute(x))
    dframe <- cbind(dframe, dummy(dframe[[x]], sep = "_"))
    return(dframe)
}

dummy_df(df1, year)
dummy_df(df1, "year")

编辑

OP's comment 之后,保留或删除列x 可以通过额外的函数参数keep 解决,默认为TRUE

dummy_df <- function(dframe, x, keep = TRUE){
    x <- as.character(substitute(x))
    if(keep){
        dftmp <- dframe
    } else {
        i <- grep(x, names(dframe))
        if(length(i) == 0) stop(paste(sQuote(x), "is not a valid column"))
        dftmp <- dframe[-i]
    }
    dframe <- cbind(dftmp, dummy(dframe[[x]], sep = "_"))
    return(dframe)
}

dummy_df(df1, year)
dummy_df(df1, "year")

dummy_df(df1, year, keep = FALSE)
dummy_df(df1, month, keep = FALSE)

【讨论】:

  • 是否可以在函数本身中保留year(为其创建虚拟变量的列)列。现在我正在做,x &lt;- dummy_df(df1, year),然后是x &lt;- x[ ,-2]
猜你喜欢
  • 2015-10-09
  • 1970-01-01
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2010-09-09
  • 2021-07-16
相关资源
最近更新 更多