【问题标题】:An efficient way of converting a vector of characters into integers based on frequency in R一种基于R中的频率将字符向量转换为整数的有效方法
【发布时间】:2013-08-05 08:35:40
【问题描述】:

我有一个仅包含“a”或“g”的字符向量,我想根据频率将它们转换为整数,例如,更频繁的一个应该编码为 0,另一个编码为 1 :

set.seed(17)
x = sample(c('g', 'a'), 10, replace=T)
x
# [1] "g" "a" "g" "a" "g" "a" "g" "g" "a" "g"
x[x == names(which.max(table(x)))] = 0
x[x != 0] = 1
x
# [1] "0" "1" "0" "1" "0" "1" "0" "0" "1" "0"

这可行,但我想知道是否有更有效的方法。

(我们不必在这里考虑 50%-50% 的情况,因为它不应该在我们的研究中发生。)

【问题讨论】:

    标签: r data-manipulation


    【解决方案1】:

    使用这个:

    ag.encode <- function(x)
    {
      result <- x == "a"
      if( sum(result) > length(result) %/% 2 ) 1-result else as.numeric(result)
    }
    

    如果您想将标签保留在 factor 结构中,请改用:

    ag.encode2factor <- function(x)
    {
      result <- x == "a"
      if( sum(result) > length(result) %/% 2 )
      {
         factor(2-result, labels=c("a","g"))
      }
      else
      {
         factor(result+1, labels=c("g","a"))
      }
    }
    

    【讨论】:

    • 这种方式确实更快。为什么?
    • 来自data.table%chin%(仅用于字符向量)比%in%== 快。所以,x %chin% "a" 应该会快一点。
    【解决方案2】:

    您可以将您的字符向量转换为factor 之一。这个解决方案更通用,因为您不需要知道用于创建 x 的 2 个字符的名称。

    y <- as.integer(factor(x))-1
    if(sum(y)>length(y)/2) y <- as.integer(!y)
    

    【讨论】:

    • 这个比@Ferdinand.kraft 的解决方案慢,但仍然比我的快。谢谢。
    • 首选factor(x, levels = names(sort(table(x), decreasing = TRUE)))) - 1L。适用于任意数量的关卡。
    • @flodel 与1 相比,1L 会带来什么好处?我在核心 R 函数中看到了很多。
    • @flodel 您的评论中有一个额外的括号。它还发出警告消息,结果是 NAs 的向量
    • 应该是as.integer(factor(x, levels = names(sort(table(x), decreasing = TRUE)))) - 1Las.integer 返回一个 integer 向量,因此您要减去 1L(整数)而不是 1(数字)以保留 integer 向量。当您的意思是使用整数而不是数字时,它可以在许多方面受益。整数使用更少的内存,使用它们的一些操作要快得多,并且它们更健壮,因为它们不受浮点问题的影响。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多