数据转换避免了R中的嵌套循环

时间:2012-09-08 02:19:22

标签: r transform nested-loops

我有一个列为6列37行的列联表数据矩阵。 我需要应用Chi平方变换来给出行轮廓和柱轮廓以进行对应分析。

不幸的是,我被告知我需要使用嵌套循环来转换数据并执行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 

1 个答案:

答案 0 :(得分:1)

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

Xtrans [i,j] = X [i,j] / 总和( X [我,])* sqrt(总和( X [,j]))

要获得表示术语的矩阵 - 总和( X [i,])* sqrt(总和( 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

以大致相同的方式计算行变换。

做手计算,我可以确认我的解决方案是正确的,前提是我正确理解了你的索引符号(意思是我代表行,j代表列)。您期望的数字不是您所期望的数字。告诉你:

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

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

如果您不想使用此更正,那么您也可以按如下方式获得列转换:

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