我如何快速找出两个(大)因素是否相互重新标记?
How do I quickly find out whether two (large) factors are relabelings of each other?
我有两个因子向量,怀疑它们携带相同的信息直到重新标记。我怎样才能确定这是否正确?
我的问题是两个向量都很长(200,000 个条目),具有大量级别 (4,000)。有些级别非常频繁,但有 "long tail" 个级别每个级别只出现一次。
这是一个可重现的例子(抱歉,我找不到一种方法来压缩它并仍然显示我的数据的属性):
foo <- structure(c(3213L, 428L, 104L, 59L, 23L, 17L, 15L, 9L, 5L, 6L,
1L, 5L, 3L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Dim = 69L, .Dimnames = structure(list(
c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
"12", "13", "14", "15", "16", "23", "33", "83", "205", "246",
"255", "319", "374", "379", "389", "552", "566", "595", "686",
"750", "846", "965", "999", "1006", "1254", "1514", "1535",
"1605", "1687", "1744", "1792", "1937", "1946", "2166", "2198",
"2206", "2420", "2503", "2736", "2965", "2986", "3036", "3273",
"3734", "4026", "4073", "4279", "5038", "5040", "5185", "5607",
"6298", "6609", "6930", "15392", "21083", "22933", "29357"
)), .Names = ""), class = "table")
bar <- as.numeric(rep(names(foo),times=foo))
factor.1 <- as.factor(rep(paste0("a",sprintf("%04i",1:length(bar))),times=bar))
set.seed(1)
factor.2 <- as.factor(sample(gsub("a","b",unique(factor.1)),length(unique(factor.1)))[
as.numeric(factor.1)])
在这个练习之后,factor.1
和 factor.2
只是彼此的重新标记。那么,我们如何才能确定这是否适用于新向量?
不起作用的东西:
内部整数编码不需要相同,所以简单检查是否cor(as.numeric(factor.1),as.numeric(factor.2))==1
不行。
我尝试检查 factor.1
的每个因子水平是否恰好对应 factor.2
的一个因子水平,反之亦然。不幸的是,这花费的时间太长了,大约几个小时:
foo <- by(factor.1,factor.2,FUN=function(zz)length(unique(zz)))
bar <- by(factor.2,factor.1,FUN=function(zz)length(unique(zz)))
all(foo) & all(bar)
如果我们可以将 factor.1
完美地拟合到使用 factor.2
作为预测变量的多项式模型中,反之亦然,两者都携带相同的信息。不幸的是,nnet::multinom(factor.1~factor.2)
产生了可怕的 "cannot allocate a vector of size XX" 错误。 randomForest::randomForest()
,这至少会给我们一个概率答案,不能处理超过 53 个水平的因素。
我们可以 运行 table(factor.1,factor.2)
并检查是否每一行都有一个非零条目。再次 运行 内存不足。
第一个函数计算其参数的唯一元素的数量,第二个函数 returns 如果 y 的每个级别都有一个 x 级别,则为 TRUE。如果 factor.1 和 factor.2 是这样,并且如果它们使用相同数量的级别,则一个是另一个的重新标记。使用给定的数据,它立即 returns 所以它看起来非常快。最后一行是您的一个想法的快速版本。使用其中之一。
cnt <- function(x) length(unique(x))
all_one <- function(x, y) all(tapply(unclass(x), y, cnt) == 1)
# solution 1
all_one(factor.1, factor.2) && cnt(factor.1) == cnt(factor.2)
# solution 2
all_one(factor.1, factor.2) && all_one(factor.2, factor.1)
我有两个因子向量,怀疑它们携带相同的信息直到重新标记。我怎样才能确定这是否正确?
我的问题是两个向量都很长(200,000 个条目),具有大量级别 (4,000)。有些级别非常频繁,但有 "long tail" 个级别每个级别只出现一次。
这是一个可重现的例子(抱歉,我找不到一种方法来压缩它并仍然显示我的数据的属性):
foo <- structure(c(3213L, 428L, 104L, 59L, 23L, 17L, 15L, 9L, 5L, 6L,
1L, 5L, 3L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Dim = 69L, .Dimnames = structure(list(
c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11",
"12", "13", "14", "15", "16", "23", "33", "83", "205", "246",
"255", "319", "374", "379", "389", "552", "566", "595", "686",
"750", "846", "965", "999", "1006", "1254", "1514", "1535",
"1605", "1687", "1744", "1792", "1937", "1946", "2166", "2198",
"2206", "2420", "2503", "2736", "2965", "2986", "3036", "3273",
"3734", "4026", "4073", "4279", "5038", "5040", "5185", "5607",
"6298", "6609", "6930", "15392", "21083", "22933", "29357"
)), .Names = ""), class = "table")
bar <- as.numeric(rep(names(foo),times=foo))
factor.1 <- as.factor(rep(paste0("a",sprintf("%04i",1:length(bar))),times=bar))
set.seed(1)
factor.2 <- as.factor(sample(gsub("a","b",unique(factor.1)),length(unique(factor.1)))[
as.numeric(factor.1)])
在这个练习之后,factor.1
和 factor.2
只是彼此的重新标记。那么,我们如何才能确定这是否适用于新向量?
不起作用的东西:
内部整数编码不需要相同,所以简单检查是否
cor(as.numeric(factor.1),as.numeric(factor.2))==1
不行。我尝试检查
factor.1
的每个因子水平是否恰好对应factor.2
的一个因子水平,反之亦然。不幸的是,这花费的时间太长了,大约几个小时:foo <- by(factor.1,factor.2,FUN=function(zz)length(unique(zz))) bar <- by(factor.2,factor.1,FUN=function(zz)length(unique(zz))) all(foo) & all(bar)
如果我们可以将
factor.1
完美地拟合到使用factor.2
作为预测变量的多项式模型中,反之亦然,两者都携带相同的信息。不幸的是,nnet::multinom(factor.1~factor.2)
产生了可怕的 "cannot allocate a vector of size XX" 错误。randomForest::randomForest()
,这至少会给我们一个概率答案,不能处理超过 53 个水平的因素。我们可以 运行
table(factor.1,factor.2)
并检查是否每一行都有一个非零条目。再次 运行 内存不足。
第一个函数计算其参数的唯一元素的数量,第二个函数 returns 如果 y 的每个级别都有一个 x 级别,则为 TRUE。如果 factor.1 和 factor.2 是这样,并且如果它们使用相同数量的级别,则一个是另一个的重新标记。使用给定的数据,它立即 returns 所以它看起来非常快。最后一行是您的一个想法的快速版本。使用其中之一。
cnt <- function(x) length(unique(x))
all_one <- function(x, y) all(tapply(unclass(x), y, cnt) == 1)
# solution 1
all_one(factor.1, factor.2) && cnt(factor.1) == cnt(factor.2)
# solution 2
all_one(factor.1, factor.2) && all_one(factor.2, factor.1)