【问题标题】:Data transformation avoiding nested loops in R数据转换避免 R 中的嵌套循环
【发布时间】:2012-09-01 21:27:16
【问题描述】:

我有一个 6 列 37 行的列联表数据矩阵。 我需要应用卡方变换来为我提供行配置文件和列配置文件以进行对应分析。

不幸的是,有人告诉我我需要使用嵌套循环来转换数据并执行 CA(而不是在 R 中使用更明智的方式)。我获得了用于嵌套循环的结构:

transformed.data=data0

for (row.index in 1:nrow(data)) {
  for (col.index in 1:ncol(data)) {
    transfomed.data[row.index,col.index]=
       "TRANSFORMATION"[row.index,col.index]
  }
}

据我了解,通过使用嵌套循环,它会先将我的 "TRANSFORMATION" 应用到行,然后再应用到列。

我想要对数据进行的转换以获取行配置文件是:

( X( ij ) / sum( X( i ) ) ) / sqrt( sum( X( j ) ) )

虽然我想对数据进行转换以获取列配置文件是:

( X( ij ) / sum( X( j ) ) ) / sqrt( sum( X( i ) ) )

我会在嵌套循环的最后一行输入什么作为我的 "TRANSFORMATION" 以使其输出我想要的配置文件转换。否则,如果我在这里没有理解嵌套循环的意义,请描述它可以让我做什么。

这是我的数据子集的代码:

matrix(c(15366,2079,411,366,23223,2667,699,819,31632,2724,717,1473,49938,3111,1062,11964)
,nrow=4,ncol=4,byrow=T)

所以单独使用这个子集,我希望第一行的行配置文件是:

0.002432689 0.0003291397 6.506803e-05 5.794379e-05

第一列的列配置文件是:

0.0009473414, 0.0132572344, 0.0572742202, 0.0132863528 

【问题讨论】:

  • 您能否添加一些示例数据来提出您的问题reproducible?将需要输入数据集和您的预期结果。另外,您是否搜索过内置函数?谷歌上的第一次点击给了我this
  • 谢谢大通,我将在第一篇文章中添加一些示例数据。关于这个作业的第二个问题,我必须首先通过转换数据(我坚持的一点)并对其进行 PCA 逐步进行对应分析,然后通过更明智的方式进行相关分析(原始数据)和ca(原始数据)
  • 听起来像家庭作业?几点建议。 1)您不需要任何 for 循环,2)如果您使用 colSums()rowSums(),您的公式可以变得更容易 3)当所有其他方法都失败时,您可以查看函数的源代码以了解其他作者已经解决了同样的问题。为此,请在控制台中键入不带括号的函数名称。这个可以是一个包含上述信息的单行函数。
  • 预期的结果是与原始数据具有相同行数和列数的两个矩阵吗?一个可以称为“行转换版本”,一个称为“列转换版本”?
  • %o% 函数(外部)也可能有帮助。

标签: r transform nested-loops


【解决方案1】:

您可以在这些类型的计算中使用它,甚至不需要一个循环。重写你的方程,然后你得到:

Xtrans[i,j] = X[i,j] / ( sum( X[ i, ] ) * sqrt( sum( X[ ,j] ) ) )

要获得一个表示术语的矩阵 - sum( X[i, ] ) * sqrt( sum( X[ ,j] ) ) - 你使用函数outer()%o% 像这样:

rowSums(X) %o% sqrt(colSums(X))

或者,对于列转换:

sqrt(rowSums(X)) %o% colSums(X)

您唯一需要做的就是将原始矩阵除以这个矩阵,例如用于 col 转换:

TEST <- matrix(
               c(15366,2079,411,366,23223,2667,699,819,
                 31632,2724,717,1473,49938,3111,1062,11964),
                 nrow=4,ncol=4,byrow=T)

> TEST / (sqrt(rowSums(TEST)) %o% colSums(TEST))
             [,1]        [,2]        [,3]         [,4]
[1,] 0.0009473414 0.001455559 0.001053892 0.0001854284
[2,] 0.0011674098 0.001522501 0.001461474 0.0003383284
[3,] 0.0013770523 0.001346668 0.001298230 0.0005269580
[4,] 0.0016167998 0.001143812 0.001430074 0.0031831055

您可以用大致相同的方式计算行转换。

进行手动计算,我可以确认我的解决方案是正确的,前提是我正确理解了您的索引符号(意味着 i 代表行,j 代表列)。您期望的数字不是您所说的期望的数字。给你看:

> ( TEST[1,2] / sum(TEST[,2]) ) / sqrt(sum(TEST[1,]))
[1] 0.001455559

您所说的卡方归一化,实际上可以在vegan 包的函数decostand 中找到。请注意,默认情况下,该方法通过乘以矩阵总数的平方根进行调整。这在对应分析中是有意义的。

如果你不想使用这个修正,那么你可以得到例如列转换,如下所示:

> require(vegan)
> decostand(TEST,method="chi.square",MARGIN=2)/sqrt(sum(TEST))
             [,1]         [,2]        [,3]        [,4]
[1,] 0.0009473414 0.0011674098 0.001377052 0.001616800
[2,] 0.0014555588 0.0015225011 0.001346668 0.001143812
[3,] 0.0010538924 0.0014614736 0.001298230 0.001430074
[4,] 0.0001854284 0.0003383284 0.000526958 0.003183106
attr(,"decostand")
[1] "chi.square"

【讨论】:

  • 我知道这是作业,但我想我们已经过了作业的截止日期,因此添加了一个实际上类似于 R 的解决方案
猜你喜欢
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 2017-08-27
  • 2017-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多