【问题标题】:creating a matrix of indicator variables创建指标变量矩阵
【发布时间】:2012-12-09 14:06:56
【问题描述】:

我想创建一个指标变量矩阵。我最初的想法是使用model.matrix,这里也建议:Automatically expanding an R factor into a collection of 1/0 indicator variables for every factor level

但是,如果因子只有一个级别,model.matrix 似乎不起作用。

这是一个示例数据集,其中因子“区域”具有三个级别:

dat = read.table(text = "
    reg1    reg2    reg3   
      1       0       0
      1       0       0
      1       0       0
      1       0       0
      1       0       0
      1       0       0
      0       1       0
      0       1       0
      0       1       0
      0       0       1
      0       0       1
      0       0       1
      0       0       1
", sep = "", header = TRUE)

# model.matrix works if there are multiple regions:

region <- c(1,1,1,1,1,1,2,2,2,3,3,3,3)

df.region <- as.data.frame(region)

df.region$region <- as.factor(df.region$region)

my.matrix <- as.data.frame(model.matrix(~ -1 + df.region$region, df.region))
my.matrix


# The following for-loop works even if there is only one level to the factor
# (one region):

# region <- c(1,1,1,1,1,1,1,1,1,1,1,1,1)

my.matrix <- matrix(0, nrow=length(region), ncol=length(unique(region)))

for(i in 1:length(region)) {my.matrix[i,region[i]]=1}
my.matrix

for 循环很有效,而且看起来很简单。但是,我一直在努力想出一个不涉及循环的解决方案。我可以使用上面的循环,但一直在努力摆脱它们。有没有更好的办法?

【问题讨论】:

    标签: r matrix indicator model.matrix


    【解决方案1】:

    我通过在此处修改类似问题的答案提出了这个解决方案:

    Reshaping a column from a data frame into several columns using R

    region <- c(1,1,1,1,1,1,2,2,2,3,3,3,3)
    site <- seq(1:length(region))
    df <- cbind(site, region)
    ind <- xtabs( ~ site + region, df)
    ind
    
    region <- c(1,1,1,1,1,1,1,1,1,1,1,1,1)
    site <- seq(1:length(region))
    df <- cbind(site, region)
    ind <- xtabs( ~ site + region, df)
    ind
    

    编辑:

    下面一行将从ind中提取指标变量的数据框:

    ind.matrix <- as.data.frame.matrix(ind)
    

    【讨论】:

      【解决方案2】:

      我会使用矩阵索引。来自?"["

      第三种索引形式是通过数字矩阵,每个维度有一列:索引矩阵的每一行然后选择数组的单个元素,结果是一个向量。

      利用这个不错的功能:

      my.matrix <- matrix(0, nrow=length(region), ncol=length(unique(region)))
      my.matrix[cbind(seq_along(region), region)] <- 1
      
      #       [,1] [,2] [,3]
      #  [1,]    1    0    0
      #  [2,]    1    0    0
      #  [3,]    1    0    0
      #  [4,]    1    0    0
      #  [5,]    1    0    0
      #  [6,]    1    0    0
      #  [7,]    0    1    0
      #  [8,]    0    1    0
      #  [9,]    0    1    0
      # [10,]    0    0    1
      # [11,]    0    0    1
      # [12,]    0    0    1
      # [13,]    0    0    1
      

      【讨论】:

      • +1 适用于任何使用鲜为人知但非常酷的矩阵索引功能的人。这是我的最爱。
      • 我认为 length(unique(region)) 应该改为 nlevels(region);如果缺少一个级别,矩阵将不够宽。
      • @Aaron,第一行,我从 OP 复制的。看看region是怎么定义的;这不是一个因素,所以我认为length(unique(region)) 是合适的。
      • 啊,是的,我明白了。我仍然更喜欢max 之类的东西,但如果它总是被定义为一个递增整数的序列,没有遗漏,那么任何一种方式都可以。
      猜你喜欢
      • 1970-01-01
      • 2011-09-03
      • 2013-09-15
      • 2018-11-16
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 2013-06-30
      • 1970-01-01
      相关资源
      最近更新 更多