【问题标题】:how to convert rows into factors in R?如何将行转换为R中的因子?
【发布时间】:2013-04-11 07:16:17
【问题描述】:

例如,我有一个矩阵:

> a = cbind(sample(c(0,1),6,replace=T), sample(c(0,1),6,replace=T))
> a
     [,1] [,2]
[1,]    0    0
[2,]    0    0
[3,]    0    1
[4,]    1    0
[5,]    1    0
[6,]    1    1

我想从a 中创建一个对象b,以便b 是一个因素,每个级别代表a 中的不同行。在这种情况下,b 将是:

> b
[1] 1 1 2 3 3 4
Levels: 1 2 3 4

我可以用肮脏的方式做到这一点,但我想知道是否有一个优雅的解决方案?

【问题讨论】:

  • 数据集有多大? a 总是有 2 列吗? a 将始终仅包含 integer、仅包含 numeric 还是仅包含 characters
  • 你目前使用的“肮脏”方式是什么?我们如何确保我们的方式也不脏?
  • 我认为的肮脏方式是使用paste 连接每一行。但我忘了我也可以使用apply 函数对其进行矢量化。

标签: r matrix r-factor


【解决方案1】:

一个可能的解决方案:

 b <- apply(a, 1, paste, collapse="_")
 b <- factor(b, levels=unique(b), labels=1:length(unique(b)))

【讨论】:

  • 这是我最初的想法,我认为paste 会比interaction 更快,但不确定OP 已经尝试了什么。
  • @AnandaMahto 我会说这与往常一样取决于数据量。当这个增长时,粘贴比交互更快。
  • 这不仅仅是数据量。随着交互次数的增加,由于 paste 是矢量化的,它肯定会更快。添加drop = FALSE 会加快interaction 的速度,但我不确定能提高多少。
【解决方案2】:

不知道您当前的“肮脏”方式是什么,这是一个可能的解决方案:

> aFac <- interaction(data.frame(a), lex.order=TRUE)
> factor(aFac, levels = levels(aFac), labels = seq_along(levels(aFac)))
[1] 1 1 2 3 3 4
Levels: 1 2 3 4

地点:

a <- structure(c(0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 1L), 
               .Dim = c(6L, 2L), .Dimnames = list(NULL, NULL))

我使用lex.order = TRUE 的唯一原因是为了匹配您的特定输出。


另一种可能是:

> aFac <- interaction(data.frame(a), lex.order=TRUE, drop = TRUE)
> factor(as.numeric(aFac))
[1] 1 1 2 3 3 4
Levels: 1 2 3 4

drop = TRUE 是从interaction 中删除任何未使用的级别,正如我们将在下面的 cmets 中获得的示例一样。

为了证明drop = TRUE 的影响,请考虑以下因素,注意产生的因子水平:

> b <- structure(c(1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1), .Dim = c(6L,2L))
> bFac1 <- interaction(data.frame(b), lex.order=TRUE)
> bFac2 <- interaction(data.frame(b), lex.order=TRUE, drop=TRUE)
> factor(as.numeric(bFac1))
[1] 3 4 3 2 2 4
Levels: 2 3 4
> factor(as.numeric(bFac2))
[1] 2 3 2 1 1 3
Levels: 1 2 3

【讨论】:

    【解决方案3】:

    根据数据的简单性,以下可能是一种方法。

    a
    ##      V1 V2
    ## [1,]  0  0
    ## [2,]  0  0
    ## [3,]  0  1
    ## [4,]  1  0
    ## [5,]  1  0
    ## [6,]  1  1
    
    hash <- apply(a, 1, paste, collapse = "/")
    b <- factor(hash, labels = 1:length(unique(hash)))
    b
    ## [1] 1 1 2 3 3 4
    ## Levels: 1 2 3 4
    

    【讨论】:

    • 由于您的回答比 droopy 的来得晚,所以我接受了 droopy 的回答。但是谢谢! +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多