函数检查 (length (list) != 0) always returns length = 0

Function check for (length (list) != 0) always returns length = 0

我在 r-markdown 脚本中使用 UDF 来绘制存储列表中的数据。当我 运行 我的函数主体时,一切正常,但是当我尝试使用定义的参数执行函数时,我已经验证在主体中工作,我所有检查列表长度的逻辑 returns FALSE.

这是我制作的示例数据集:

library(dplyr)
library(plotly)

        plotdataframe   <- list()
        dataframerows   <- list()
        AllExplVarCoeffs    <- list()
        AllExplVarNames <- list()
        NrmPolcts   <- list()
        AllExplVarCoeff <- list()
        AllExplVarName  <- list()
        NrmPolct    <- list()
            
        
        for (i in 1:10)
        {
            for (j in 1:8)
                {
                    for(n in 1:16)
                        {   
                        
                            if (n == 3 ||   n == 8 || n == 4 && j == 5 || n == 9 && j == 5)
                            {
                                AllExplVarName      <-NULL       
                                AllExplVarCoeff <- NULL    
                                NrmPolct    <- NULL
                            }else
                                {
                                    set.seed(10)
                                    AllExplVarName      <-c(1,2,3,4,5,6,7,8,9,10)       
                                    AllExplVarCoeff <- runif(10, min=-1, max=1)    
                                    NrmPolct    <- c(.015,.005,.33,.32,.225,.025,.03,.05,0 ,0)
                                                            
                                    padvarcnt <-(length(AllExplVarCoeff)-length(NrmPolct))
                                
                                    for (l in seq_len(padvarcnt))
                                    {
                                        padval = l*0
                                        NrmPolCt1 <- c(NrmPolCt,padval)
                                    }
                                    NrmPolct1 <- as.numeric(unlist(NrmPolct))
                                    
                                    AllExplVarNames <- cbind(AllExplVarNames,AllExplVarName) 
                                    AllExplVarCoeffs    <- cbind(AllExplVarCoeffs,AllExplVarCoeff)
                                    NrmPolcts   <- cbind(NrmPolcts,NrmPolct1)
                                    
                                    dataframerows   <- cbind(AllExplVarNames,AllExplVarCoeffs,NrmPolcts)
                                    assign(paste("plotdataframe",i, j, n, sep="_"),cbind(plotdataframe,dataframerows)) 
                                    
                                    plotdataframe   <- list()
                                    dataframerows   <- list()
                                    AllExplVarCoeffs    <- list()
                                    AllExplVarNames <- list()
                                    NrmPolcts   <- list()
                                    
                                    assign(paste("AllExplVarNames",i, j, n, sep="_"),cbind(AllExplVarNames,AllExplVarName)) 
                                    assign(paste("AllExplVarCoeffs",i ,j ,n, sep="_"),cbind(AllExplVarCoeffs,AllExplVarCoeff))
                                    assign(paste("NrmPolcts",i, j, n, sep="_"),cbind(NrmPolcts,NrmPolct1))
                                                            
                                    AllExplVarCoeffs    <- list()
                                    AllExplVarNames <- list()
                                    NrmPolcts   <- list()
                                }
                        }
                }
        }

NULL 条目表示在我的真实数据中“n”的值将 return 为空集的情况。 我的功能是这样定义的(请忽略丑陋的情节,我时间紧所以我没有把它弄得好看):

    DrawTestExVar   <- function(x,j)
    {
    
        print(paste("x=",x))
        print(paste("j=",j))
        StCrPltData <- ls(pattern=paste0("plotdataframe_",x,"_",j))
        SCPD <- mget(StCrPltData)
        
        for(n in 1:16)
        {   print(paste("n=",n))
            print(paste0('plotdataframe_',x,'_',j,'_',n))
            if (length(unlist((SCPD[c(paste0('plotdataframe_',x,'_',j,'_',n))]))) != 0)
            {
                n1=n
                j1=j
                print(n1)
                plot1 <- plot_ly(as.data.frame(SCPD[c(paste0('plotdataframe_',x,'_',j,'_',n1))])) %>%
                add_trace(x=~unlist(SCPD[c(paste0('plotdataframe_',x,'_',j,'_',n1))][[1]][,'AllExplVarName']), y=~unlist(SCPD[c(paste0('plotdataframe_',x,'_',j,'_',n1))][[1]][,'AllExplVarCoeff']), yaxis="y", type="scatter", mode="markers", name="Coef Values") %>%
                add_bars(x=~unlist(SCPD[c(paste0('plotdataframe_',x,'_',j,'_',n1))][[1]][,'AllExplVarName']), y=~unlist(SCPD[c(paste0('plotdataframe_',x,'_',j,'_',n1))][[1]][,'NrmPolct1']),  yaxis="y2", name="% Polcy Count")
                
                print(plot1)
            } else
                {
                    print("Next")
                }
        }
    }

但是当我执行函数时:DrawTestExVar(5,3) 我注意到但长度 = 0 响应:

> DrawTestExVar(5,3)
[1] "x= 5"
[1] "j= 3"
[1] "n= 1"
[1] "plotdataframe_5_3_1"
[1] "Next"
[1] "n= 2"
[1] "plotdataframe_5_3_2"
[1] "Next"
[1] "n= 3"
[1] "plotdataframe_5_3_3"
[1] "Next"
[1] "n= 4"
[1] "plotdataframe_5_3_4"
[1] "Next"
[1] "n= 5"
[1] "plotdataframe_5_3_5"
[1] "Next"
[1] "n= 6"
[1] "plotdataframe_5_3_6"
[1] "Next"
[1] "n= 7"
[1] "plotdataframe_5_3_7"
[1] "Next"
[1] "n= 8"
[1] "plotdataframe_5_3_8"
[1] "Next"
[1] "n= 9"
[1] "plotdataframe_5_3_9"
[1] "Next"
[1] "n= 10"
[1] "plotdataframe_5_3_10"
[1] "Next"
[1] "n= 11"
[1] "plotdataframe_5_3_11"
[1] "Next"
[1] "n= 12"
[1] "plotdataframe_5_3_12"
[1] "Next"
[1] "n= 13"
[1] "plotdataframe_5_3_13"
[1] "Next"
[1] "n= 14"
[1] "plotdataframe_5_3_14"
[1] "Next"
[1] "n= 15"
[1] "plotdataframe_5_3_15"
[1] "Next"
[1] "n= 16"
[1] "plotdataframe_5_3_16"
[1] "Next"

我觉得比较简单; select 来自全局环境的名称与输入模式匹配的列表,然后过滤掉 return 长度为 0 列表的“n”值,并在循环中绘制余数。我已经构建了另外两个函数来从存储的数据中绘制出工作正常的函数,所以我相信问题出在 if else 循环中,问题似乎源于我如何定义或使用我的参数。 None 我对 r 函数文档的深入研究揭示了我做错了什么,并且 none 我为使调用更明确所做的尝试都奏效了。 想法?

更新 1:打印一些故障排除语句后,很明显错误实际上出在正在读取或应用的参数中。当我 print() x 和 j 的值时,当 运行 设置 DrawTestExVar(5,3) 时,x=5 和 j=3,根据需要。 print()循环中 n 的值显示它适当递增并正确应用于粘贴命令,但所有 print(length(list)) return 长度为 0.

答案在于构建函数的方式及其访问数据的方式。列表引用

StCrPltData <- ls(pattern=paste0("plotdataframe_",x,"_",j))

SCPD <- mget(StCrPltData)

需要发生在函数之外,这样它才能真正访问数据帧。此外,可以通过在函数调用中使用其定义来完全删除 StCrPltData。函数参数应该看起来像

DrawTestExVar   <- function(x,j,SCPD)

并调用函数

DrawTestExVar(5,3,mget(ls(pattern=paste0("plotdataframe_",5,"_",3))))

运行 这给出了情节(我不会展示,因为它们非常丑陋),故障排除打印:

> DrawTestExVar(5,3,mget(ls(pattern=paste0("plotdataframe_",5,"_",3))))
[1] "x= 5"
[1] "j= 3"
[1] "n= 1"
[1] "plotdataframe_5_3_1"
[1] 1
[1] "n= 2"
[1] "plotdataframe_5_3_2"
[1] 2
[1] "n= 3"
[1] "plotdataframe_5_3_3"
[1] "Next"
[1] "n= 4"
[1] "plotdataframe_5_3_4"
[1] 4
[1] "n= 5"
[1] "plotdataframe_5_3_5"
[1] 5
[1] "n= 6"
[1] "plotdataframe_5_3_6"
[1] 6
[1] "n= 7"
[1] "plotdataframe_5_3_7"
[1] 7
[1] "n= 8"
[1] "plotdataframe_5_3_8"
[1] "Next"
[1] "n= 9"
[1] "plotdataframe_5_3_9"
[1] 9
[1] "n= 10"
[1] "plotdataframe_5_3_10"
[1] 10
[1] "n= 11"
[1] "plotdataframe_5_3_11"
[1] 11
[1] "n= 12"
[1] "plotdataframe_5_3_12"
[1] 12
[1] "n= 13"
[1] "plotdataframe_5_3_13"
[1] 13
[1] "n= 14"
[1] "plotdataframe_5_3_14"
[1] 14
[1] "n= 15"
[1] "plotdataframe_5_3_15"
[1] 15
[1] "n= 16"
[1] "plotdataframe_5_3_16"
[1] 16

它遵循预期的输出,表明函数正在按预期工作。