R 函数适用于某些数据帧,但不适用于其他数据帧?

标签 r function

我有一个数据框,它总结了传递给它的数据框中缺失和非缺失观测值的数量[1]。然后,我被要求测试我所拥有的数据中两个治疗组之间的差异(我个人不同意这样做的必要性或效用,但这是我被要求做的)。所以我写了一个小函数来做到这一点......

quick.test <- function(x, y){
  chisq   <- chisq.test(x = x,  y = y)
  fisher  <- fisher.test(x = x, y = y)
  results <- cbind(chisq  = chisq$statistic,
                   df     = chisq$parameter,
                   p      = chisq$p.value,
                   fisher = fisher$p.value)
  results
}

然后我使用 apply() 将相关列传递给该函数,如下所示...

apply(miss.t1, 1, function(x) quick.test(x[2:3], x[4:5]))

这对于上面指定的 miss.t1 数据框来说很好,但我正在处理时间序列数据并且有三个时间点我想总结,所以有 miss.t2 和 miss.t3 (每个都是总结每个时间点存在/缺失数据的数量,并使用[1]中描述的函数以相同的方式创建。

miss.t2 失败并出现以下错误...

apply(miss.t2, 1, function(x) quick.test(x[2:3], x[4:5]))
Error in chisq.test(x = x, y = y) : 
  'x' and 'y' must have at least 2 levels

我最初的想法是其中一列由于某种原因缺少值,但事实似乎并非如此......

> describe(miss.t2)
miss.t2 

 5  Variables      171  Observations
--------------------------------------------------------------------------------
variable 
      n missing  unique 
    171       0     171 

lowest : Abtotal   Abyn      agg_ment  agg_phys  All.score
highest: z_pf      z_re      z_rp      z_sf      z_vt      
--------------------------------------------------------------------------------
nmiss.1 
      n missing  unique    Mean 
    171       0       4   8.649 

0 (6, 4%), 8 (9, 5%), 9 (153, 89%), 10 (3, 2%) 
--------------------------------------------------------------------------------
npresent.1 
      n missing  unique    Mean 
    171       0       4   9.351 

8 (3, 2%), 9 (153, 89%), 10 (9, 5%), 18 (6, 4%) 
--------------------------------------------------------------------------------
nmiss.2 
      n missing  unique    Mean 
    171       0       4   10.65 

0 (6, 4%), 11 (160, 94%), 12 (4, 2%), 13 (1, 1%) 
--------------------------------------------------------------------------------
npresent.2 
      n missing  unique    Mean 
    171       0       4   14.35 

12 (1, 1%), 13 (4, 2%), 14 (160, 94%), 25 (6, 4%) 
--------------------------------------------------------------------------------

接下来我尝试的是通过获取 head(miss.t2, n=XX) 来尝试 miss.t2 的子集,并且它在第 54 行之前都可以正常工作...

> apply(head(miss.t2, n=53), 1, function(x) quick.test(x[2:3], x[4:5]))
     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
[1,] 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
[2,] 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
[3,] 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
[4,] 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
     29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
[1,]  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
[2,]  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
[3,]  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
[4,]  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
There were 50 or more warnings (use warnings() to see the first 50)
> apply(head(miss.t2, n=54), 1, function(x) quick.test(x[2:3], x[4:5]))
Error in chisq.test(x = x, y = y) : 
  'x' and 'y' must have at least 2 levels
> miss.t2[54,]
   variable nmiss.1 npresent.1 nmiss.2 npresent.2
54      psq      10          8      11         14
> traceback()
5: stop("'x' and 'y' must have at least 2 levels") at #2
4: chisq.test(x = x, y = y) at #2
3: quick.test(x[2:3], x[4:5])
2: FUN(newX[, i], ...)
1: apply(head(miss.t2, n = 54), 1, function(x) quick.test(x[2:3], 
       x[4:5]))

与数据框的“底部”类似,最后 26 行可以很好地解析,但倒数第 27 行则不然......

> apply(tail(miss.t2, n=26), 1, function(x) quick.test(x[2:3], x[4:5]))
     146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
[1,]   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
[2,]   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
[3,]   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
[4,]   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
     164 165 166 167 168 169 170 171
[1,]   0   0   0   0   0   0   0   0
[2,]   1   1   1   1   1   1   1   1
[3,]   1   1   1   1   1   1   1   1
[4,]   1   1   1   1   1   1   1   1
There were 26 warnings (use warnings() to see them)
> apply(tail(miss.t2, n=27), 1, function(x) quick.test(x[2:3], x[4:5]))
Error in chisq.test(x = x, y = y) : 
  'x' and 'y' must have at least 2 levels
In addition: Warning message:
In chisq.test(x = x, y = y) : Chi-squared approximation may be incorrect

> miss.t2[118,]
    variable nmiss.1 npresent.1 nmiss.2 npresent.2
118     sf16       9          9      11         14

我看不出这两行有任何问题,这意味着它们应该失败,并且上面显示的traceback()没有透露任何有用的信息(在我看来)。

任何人都可以就问题的原因或问题提出任何建议吗?

提前非常感谢,

尼尔

编辑:对 Vincent Zoonekynd 的格式化回复...

我选择了 ?chisq.test() 中描述的 chisq.test(x = x, y = y) 版本,使用 cbind() 按照您的建议生成矩阵结果 sum(x) 中的错误:参数的“类型”(字符)无效。

放置 print 语句并显示 x 和 y 的长度会导致相同的错误,但显示的值和长度为...

> miss.t2.res <- data.frame(t(apply(miss.t2, 1, function(x) quick.test(x[2:3], x[4:5])))) 
[1] "Your x is : 9" "Your x is : 9" 
[1] 2    ### < Length of x
[1] "Your y is : 11" "Your y is : 14"
[1] 2    ### < Length of y
Error in chisq.test(x = x, y = y) : 'x' and 'y' must have at least 2 levels

编辑2:感谢 Vincent Zoonekynd 指针,问题是因为两个单元格的计数相同,所以对 chisq.test() 的调用将它们视为因子并折叠它们。解决方案是修改 fast.test() 函数并强制传递到矩阵中的参数,因此现在有效的函数是......

quick.test <- function(x, y){
  chisq   <- chisq.test(rbind(as.numeric(x), as.numeric(y)))
  fisher  <- fisher.test(rbind(as.numeric(x), as.numeric(y)))
  results <- cbind(chisq  = chisq$statistic,
                   df     = chisq$parameter,
                   p      = chisq$p.value,
                   fisher = fisher$p.value)
  results
}

非常感谢文森特的帮助和指点,非常感谢。

[1] http://gettinggeneticsdone.blogspot.co.uk/2011/02/summarize-missing-data-for-all.html

最佳答案

Vincent Zoonkeynd 在上面的评论中建议的解决方案是修改 fast.test() 函数并强制传递到矩阵中的参数,所以现在有效的函数是......

quick.test <- function(x, y){
  chisq   <- chisq.test(rbind(as.numeric(x), as.numeric(y)))
  fisher  <- fisher.test(rbind(as.numeric(x), as.numeric(y)))
  results <- cbind(chisq  = chisq$statistic,
                   df     = chisq$parameter,
                   p      = chisq$p.value,
                   fisher = fisher$p.value)
  results
}

关于R 函数适用于某些数据帧,但不适用于其他数据帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10945718/

相关文章:

r - foreach dopar 循环内的绘图

c++ - Rcpp:链接到 Shogun C++ 文件时出现问题

Python 定义函数只输出第一个目录

python - 函数定义、类型错误

javascript - JQuery - 将字符串转换为对象并添加 "click"事件在模块模式中不起作用

javascript - 类方法不是函数吗?

r - 如何使用 plotly 中的单击获取数据点标签

使用模式 mutate_at 重命名多个变量

r - 使用 RestRserve 上传 XLSX 数据

javascript - 如何防止触发传入 javascript 函数的回调