从互斥虚拟变量创建分类变量

ECI*_*CII 2 r dataframe categorical-data dummy-variable

如何从互斥虚拟变量(取值 0/1)创建分类变量?

基本上我正在寻找与此解决方案完全相反的解决方案:(https://subscription.packtpub.com/book/big_data_and_business_intelligence/9781787124479/1/01lvl1sec22/creating-dummies-for-categorical-variables)。

希望有一个基本的 R 解决方案。

例如,我有以下数据:

dummy.df <- structure(c(1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 
                        0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 
                        0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 1L), 
            .Dim = c(10L, 4L), 
            .Dimnames = list(NULL, c("State.NJ", "State.NY", "State.TX", "State.VA")))
Run Code Online (Sandbox Code Playgroud)
          State.NJ State.NY State.TX State.VA
     [1,]        1        0        0        0
     [2,]        0        1        0        0
     [3,]        1        0        0        0
     [4,]        0        0        0        1
     [5,]        0        1        0        0
     [6,]        0        0        1        0
     [7,]        1        0        0        0
     [8,]        0        0        0        1
     [9,]        0        0        1        0
    [10,]        0        0        0        1
Run Code Online (Sandbox Code Playgroud)

我想得到以下结果

   state
1     NJ
2     NY
3     NJ
4     VA
5     NY
6     TX
7     NJ
8     VA
9     TX
10    VA

cat.var <- structure(list(state = structure(c(1L, 2L, 1L, 4L, 2L, 3L, 1L, 
4L, 3L, 4L), .Label = c("NJ", "NY", "TX", "VA"), class = "factor")), 
                    class = "data.frame", row.names = c(NA, -10L))
Run Code Online (Sandbox Code Playgroud)

ulf*_*der 5

# toy data
df <- data.frame(a = c(1,0,0,0,0), b = c(0,1,0,1,0), c = c(0,0,1,0,1))

df$cat <- apply(df, 1, function(i) names(df)[which(i == 1)])
Run Code Online (Sandbox Code Playgroud)

结果:

> df
  a b c cat
1 1 0 0   a
2 0 1 0   b
3 0 0 1   c
4 0 1 0   b
5 0 0 1   c
Run Code Online (Sandbox Code Playgroud)

概括地说,您需要使用dfnames(df)部分,但您会明白要点。一种选择是创建一个函数,例如

catmaker <- function(data, varnames, catname) {

  data[,catname] <- apply(data[,varnames], 1, function(i) varnames[which(i == 1)])

  return(data)

}

newdf <- catmaker(data = df, varnames = c("a", "b", "c"), catname = "newcat")
Run Code Online (Sandbox Code Playgroud)

函数式方法的一个优点是,它对于输入的列名称向量中的名称顺序的变化具有鲁棒性。即,varnames = c("c", "a", "b")产生与 相同的结果varnames = c("a", "b", "c")

PS 在我发布此内容后,您添加了一些示例数据。该函数适用于您的示例,只要您dummy.df首先转换为数据帧,例如,catmaker(data = as.data.frame(dummy.df), varnames = colnames(dummy.df), "State")即可完成工作。