在R中,基于字符向量频率将其转换为整数的高效方法

3

我有一个由字符“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%的情况,因为在我们的研究中它不应该发生。)

2个回答

3

使用这个:

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"))
  }
}

这样确实更快。为什么? - qed
1
data.table 中的 %chin%(仅适用于字符向量)比 %in%== 更快。因此,使用 x %chin% "a" 可以稍微提高速度。 - Arun

3
您可以将字符向量转换为因子(factor)向量。这种方法更为通用,因为您不需要知道用于创建x的2个字符的名称。
y <- as.integer(factor(x))-1
if(sum(y)>length(y)/2) y <- as.integer(!y)

这个比@Ferdinand.kraft的解决方案慢,但仍然比我的快。谢谢。 - qed
1
更倾向于使用 factor(x, levels = names(sort(table(x), decreasing = TRUE)))) - 1L。适用于任意数量的水平。 - flodel
@flodel,相比于11L会带来哪些好处?我在R核心函数中经常看到这个。 - qed
@flodel,你的评论中有一个多余的括号。此外,它会给出一个警告信息,结果是NA向量。 - qed
应该是 as.integer(factor(x, levels = names(sort(table(x), decreasing = TRUE)))) - 1Las.integer 返回一个整数向量,因此您要减去 1L(一个整数),而不是 1(一个数字)以保留一个整数向量。在需要时使用整数而不是数字可以在许多方面受益。整数使用更少的内存,一些使用它们的操作速度更快,并且它们更健壮,因为它们不会受到浮点问题的影响。 - flodel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接