在列表上应用嵌套循环的麻烦

时间:2012-11-06 15:23:55

标签: r

我有一个由3个元素组成的列表:

datalist=list(a=datanew1,b=datanew2,c=datanew3)

datalist $ a:

      Inv_ret Firm size  leverage        Risk  Liquidity Equity
17  0.04555968  17.34834 0.1323199 0.011292273 0.02471489      0
48  0.01405835  15.86315 0.6931730 0.002491093 0.12054914      0
109 0.04556252  16.91602 0.1714068 0.006235836 0.01194579      0
159 0.04753472  14.77039 0.3885720 0.007126830 0.06373028      0
301 0.03941040  16.94377 0.1805346 0.005450653 0.01723319      0

datalist $ b:

      Inv_ret Firm size   leverage        Risk  Liquidity      Equity
31  0.04020832  18.13300 0.09326265 0.015235240 0.01579559 0.005025379
62  0.04439078  17.84086 0.11016402 0.005486982 0.01266566 0.006559096
123 0.04543250  18.00517 0.12215307 0.011154742 0.01531451 0.002282790
173 0.03960613  16.45457 0.10828643 0.011506857 0.02385191 0.009003780
180 0.03139643  17.57671 0.40063094 0.003447233 0.04530395 0.000000000

datalist $ c:

   Inv_ret Firm size   leverage       Risk   Liquidity      Equity
92  0.03081029  19.25359 0.10513159 0.01635201 0.025760806 0.000119744
153 0.03280746  19.90229 0.11731517 0.01443786 0.006769735 0.011999005
210 0.04655847  20.12543 0.11622403 0.01418010 0.003125632 0.003802365
250 0.03301018  20.67197 0.13208234 0.01262499 0.009418828 0.021400052
282 0.04355975  20.03012 0.08588316 0.01918129 0.004213846 0.023657440

我正在尝试在cor.test上面创建datalist

Cor.tests=sapply(datalist,function(x){ 
  for(h in 1:length(names(x))){

    for(i in 1:length(names(x$h[i]))){
      for(j in 1:length(names(x$h[j]))){
      cor.test(x$h[,i],x$h[,j])$p.value 


    }}}})

但我得到error

Error in cor.test.default(x$h[, i], x$h[, j]) : 
  'x' must be a numeric vector

关于我做错了什么的任何建议?

P.S。如果我只有一个数据框datanew1

      Inv_ret Firm size  leverage        Risk  Liquidity Equity
17  0.04555968  17.34834 0.1323199 0.011292273 0.02471489      0
48  0.01405835  15.86315 0.6931730 0.002491093 0.12054914      0
109 0.04556252  16.91602 0.1714068 0.006235836 0.01194579      0
159 0.04753472  14.77039 0.3885720 0.007126830 0.06373028      0
301 0.03941040  16.94377 0.1805346 0.005450653 0.01723319      0

我使用此loop

results=matrix(NA,nrow=6,ncol=6)
for(i in 1:length(names(datanew1))){
  for(j in 1:length(names(datanew1))){
    results[i,j]<-cor.test(datanew1[,i],datanew1[,j])$p.value 


}}

输出是:

results :
             [,1]         [,2]         [,3]         [,4]         [,5]        [,6]
[1,] 0.000000e+00 7.085663e-09 3.128975e-10 3.018239e-02 4.806400e-10 0.475139526
[2,] 7.085663e-09 0.000000e+00 2.141581e-21 0.000000e+00 2.247825e-20 0.454032499
[3,] 3.128975e-10 2.141581e-21 0.000000e+00 2.485924e-25 2.220446e-16 0.108643838
[4,] 3.018239e-02 0.000000e+00 2.485924e-25 0.000000e+00 5.870007e-15 0.006783324
[5,] 4.806400e-10 2.247825e-20 2.220446e-16 5.870007e-15 0.000000e+00 0.558827862
[6,] 4.751395e-01 4.540325e-01 1.086438e-01 6.783324e-03 5.588279e-01 0.000000000

这正是我想要的。但是我希望获得3个矩阵,一个用于上面datalist的每个元素。

EDIT: 如果我像朱兰所说的那样:

Cor.tests=lapply(datalist,function(x){ 

  results=matrix(NA,nrow=6,ncol=6)
  for(i in 1:length(names(x))){
    for(j in 1:length(names(x))){
      results[i,j]<-cor.test(x[,i],x[,j])$p.value 
    }}})

我明白了:

$a
NULL

$b
NULL

$c
NULL

2 个答案:

答案 0 :(得分:1)

这可以在没有for循环的情况下完成。

1)具有碱基R的溶液:

lapply(datalist,
       function(datanew) outer(seq_along(datanew),
                               seq_along(datanew),
                               Vectorize(function(x, y)
                                            cor.test(datanew[ , x],
                                                     datanew[ , y])$p.value)))

2)包psych的解决方案:

library(psych)
lapply(datalist, function(datanew) corr.test(datanew)$p)

问题中修改后的方法版本:

lapply(datalist, function(x) { 
                    results <- matrix(NA,nrow=6,ncol=6)
                    for(i in 1:6){
                       for(j in 1:6){
                          results[i,j]<-cor.test(x[,i],x[,j])$p.value 
                       }
                    }
                    return(results)
                 })

这些命令存在两个主要问题:

  1. 未返回矩阵results。我添加了return(results) 功能。

  2. 您想拥有一个6乘6的矩阵,而您的数据帧却有     七列。我将1:length(names(x))替换为1:6     for循环。

答案 1 :(得分:0)

我不会尝试为您提供有效的代码,但希望以下内容有助于解释您为什么尝试不起作用。

让我们看一下sapply电话的前几行:

Cor.tests=sapply(datalist,function(x){ 
  for(h in 1:length(names(x))){
    for(i in 1:length(names(x$h[i]))){

让我们停下来思考一下x$h[i]。在这一点上,x是传递给sapply中的匿名函数的参数(可能是数据框或矩阵,我无法从您的问题中确定它是什么)。

在您的代码中,h是什么? h是上一个for循环中的索引变量,因此最初h的值为1. $运算符用于通过名称从对象中选择项目。名为x的{​​{1}}中有什么内容吗?我想不是。

但是当你试图在h里面这个名为i的不存在的东西中选择h元素时,事情变得更糟。老实说,我甚至不确定R的解释器会对此做什么,因为你在表达式中引用变量x,该表达式应该定义i的值范围。通知,任何人?

如果你只是删除第三个for循环的所有尝试,你应该有更多的运气。只需使用工作版本,将其放在匿名函数的主体中,并用i替换每个datanew1

祝你好运。

(PS - 您可能希望对x的输出感到满意,而不是lapply