代码之家  ›  专栏  ›  技术社区  ›  Brandon Bertelsen

功能内的功能未按预期激活

r
  •  2
  • Brandon Bertelsen  · 技术社区  · 14 年前

    我有一个函数,用来“快速查看”数据。框架…我处理了大量的调查数据,这是一个快速的工具,看看什么是什么。

    f.table <- function(x) {
    
        if (is.factor(x[[1]])) { 
            frequency <- function(x) {
                x <- round(length(x)/n, digits=2)
            }
            x <- na.omit(melt(x,c()))
            x <- cast(x, variable ~ value, frequency)
            x <- cbind(x,top2=x[,ncol(x)]+x[,ncol(x)-1], bottom=x[,2])
        }
    
        if (is.numeric(x[[1]])) {
            frequency <- function(x) { 
                x[x > 1] <- 1
                x[is.na(x)] <- 0
                x <- round(sum(x)/n, digits=2) 
                } 
    
            x <- na.omit(melt(x))
            x <- cast(x, variable ~ ., c(frequency, mean, sd, min, max))
            x <- transform(x, variable=reorder(variable, frequency))
        }
    
    return(x) 
    }
    

    我发现如果我不在函数外定义“频率”,它会返回带有连续变量的数据帧的不稳定结果。我在函数之外使用哪一个定义似乎无关紧要,只要我这样做。

    尝试:

    n <- 100    
    x <- data.frame(a=c(1:25),b=rnorm(100),c=rnorm(100))
    x[x > 20] <- NA 
    

    现在,选择其中一个频率函数并将其粘贴到中,然后重试:

    frequency <- function(x) {
                    x <- round(length(x)/n, digits=2)
                }
    f.table(x)
    

    为什么会这样?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Gavin Simpson    14 年前

    关键是,我认为这就是你的问题所在。 cast() 正在评估这些函数,而不引用从中调用的函数。里面 () 它评估 fun.aggregate 通过 funstofun 而且,虽然我不太明白它在做什么,但是 stats:::frequency 而不是你当地的。

    因此,我对您的问题提出了意见。您希望该函数做什么?目前,似乎有必要在全球环境中定义一个“频率”函数,以便 () funstofun() 找到它。给它取一个独特的名字,这样它就不可能与任何事物发生冲突,所以它应该是唯一被发现的东西,比如 .Frequency() . 不知道你想用函数做什么(而不是你认为函数[f.table]应该做什么),提供进一步的指导有点困难,但是为什么不 .FrequencyNum() .FrequencyFac() 在全局工作区中定义并重写 f.table() 要强制转换的包装调用是否使用相关的包装调用?

    .FrequencyFac <- function(X, N) {
        round(length(X)/N, digits=2)
    }
    
    .FrequencyNum <- function(X, N) {
        X[X > 1] <- 1
        X[is.na(X)] <- 0
        round(sum(X)/N, digits=2)
    }
    f.table <- function(x, N) {
        if (is.factor(x[[1]])) {
            x <- na.omit(melt(x, c()))
            x <- dcast(x, variable ~ value, .FrequencyFac, N = N)
            x <- cbind(x,top2=x[,ncol(x)]+x[,ncol(x)-1], bottom=x[,2])
        }
    
        if (is.numeric(x[[1]])) {
            x <- na.omit(melt(x))
            x <- cast(x, variable ~ ., c(.FrequencyNum, mean, sd, min, max), N = N)
            ##x <- transform(x, variable=reorder(variable, frequency))
            ## left this out as I wanted to see what cast returned
        }
    return(x) 
    }
    

    我认为这是可行的,但它找不到n,应该是。所以也许我错过了什么?

    顺便说一下,依靠函数 n (在您的版本中)从函数外部。始终将需要的变量作为参数传入。

        2
  •  0
  •   Joshua Ulrich    14 年前

    我没有包含 melt 但是我可以看到一些潜在的问题:

    1. 你的 frequency 功能没有 return 什么都行。
    2. 改变函数输入通常是不好的做法( x 是输入 输出)。
    3. 已经有一个泛型 频率 功能在 stats 包在基R中,这可能会导致方法调度出现问题(我不确定)。