如何在数据框的每一行上执行函数,并仅将输出的一个元素作为新列插入到该行中

发布于 2024-10-04 11:24:00 字数 709 浏览 0 评论 0原文

对两个值进行精确二项式测试很容易,但如果想对一大堆成功次数和试验次数进行测试会发生什么。我创建了一个包含测试敏感性、研究中潜在参与者数量的数据框,然后对于每一行,我计算了成功的可能性。这是代码。

sens <-seq(from=.1, to=.5, by=0.05)
enroll <-seq(from=20, to=200, by=20)
df <-expand.grid(sens=sens,enroll=enroll)
df <-transform(df,succes=sens*enroll)

但现在我如何使用每一行的成功和试验次数的组合来进行二项式测试。

我只对二项式检验的 95% 置信区间的上限感兴趣。我希望将该单个数字作为名为“upper.limit”的列添加到数据框中,

我想到了类似的东西

binom.test(succes,enroll)$conf.int    

,conf.int 给出了诸如

[1] 0.1266556 0.2918427
attr(,"conf.level")
[1] 0.95

我想要的只是 0.2918427

此外,我有一种感觉,那里必须有 do.call ,甚至可能是 lapply,但我不知道它将如何通过整个数据框。或者我应该使用 plyr 吗?

显然我的头在旋转。请让它停止。

It is easy to do an Exact Binomial Test on two values but what happens if one wants to do the test on a whole bunch of number of successes and number of trials. I created a dataframe of test sensitivities, potential number of enrollees in a study and then for each row I calculate how may successes that would be. Here is the code.

sens <-seq(from=.1, to=.5, by=0.05)
enroll <-seq(from=20, to=200, by=20)
df <-expand.grid(sens=sens,enroll=enroll)
df <-transform(df,succes=sens*enroll)

But now how do I use each row's combination of successes and number of trials to do the binomial test.

I am only interested in the upper limit of the 95% confidence interval of the binomial test. I want that single number to be added to the data frame as a column called "upper.limit"

I thought of something along the lines of

binom.test(succes,enroll)$conf.int    

alas, conf.int gives something such as

[1] 0.1266556 0.2918427
attr(,"conf.level")
[1] 0.95

All I want is just 0.2918427

Furthermore I have a feeling that there has to be do.call in there somewhere and maybe even an lapply but I do not know how that will go through the whole data frame. Or should I perhaps be using plyr?

Clearly my head is spinning. Please make it stop.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

折戟 2024-10-11 11:24:00

如果这给了你(几乎)你想要的,那么试试这个:

binom.test(succes,enroll)$conf.int[2]

并按原样应用于整个板或跨行:

> df$UCL <- apply(df, 1, function(x)  binom.test(x[3],x[2])$conf.int[2] )
> head(df)
  sens enroll succes       UCL
1 0.10     20      2 0.3169827
2 0.15     20      3 0.3789268
3 0.20     20      4 0.4366140
4 0.25     20      5 0.4910459
5 0.30     20      6 0.5427892
6 0.35     20      7 0.5921885

If this gives you (almost) what you want, then try this:

binom.test(succes,enroll)$conf.int[2]

And apply across the board or across the rows as it were:

> df$UCL <- apply(df, 1, function(x)  binom.test(x[3],x[2])$conf.int[2] )
> head(df)
  sens enroll succes       UCL
1 0.10     20      2 0.3169827
2 0.15     20      3 0.3789268
3 0.20     20      4 0.4366140
4 0.25     20      5 0.4910459
5 0.30     20      6 0.5427892
6 0.35     20      7 0.5921885
凶凌 2024-10-11 11:24:00

开始吧:

R> newres <- do.call(rbind, apply(df, 1, function(x) { 
+                     bt <- binom.test(x[3], x[2])$conf.int; 
+                     newdf <- data.frame(t(x), UCL=bt[2]) }))
R>
R> head(newres)
  sens enroll succes     UCL
1 0.10     20      2 0.31698
2 0.15     20      3 0.37893
3 0.20     20      4 0.43661
4 0.25     20      5 0.49105
5 0.30     20      6 0.54279
6 0.35     20      7 0.59219
R> 

这使用 apply 循环现有数据,计算测试,通过将其粘贴到新的(单行)data.frame 中来返回您想要的值。然后,我们使用 do.call(rbind, ...) 将所有这 90 个 data.frame 对象粘合到一个新的单个对象中,覆盖从 apply 获得的列表。

啊,是的,如果您只想直接插入一列,另一个答案很简单,因为它很简单。我的较长答案展示了如何在 apply 扫描期间增长或构造 data.frame

Here you go:

R> newres <- do.call(rbind, apply(df, 1, function(x) { 
+                     bt <- binom.test(x[3], x[2])$conf.int; 
+                     newdf <- data.frame(t(x), UCL=bt[2]) }))
R>
R> head(newres)
  sens enroll succes     UCL
1 0.10     20      2 0.31698
2 0.15     20      3 0.37893
3 0.20     20      4 0.43661
4 0.25     20      5 0.49105
5 0.30     20      6 0.54279
6 0.35     20      7 0.59219
R> 

This uses apply to loop over your existing data, compute test, return the value you want by sticking it into a new (one-row) data.frame. And we then glue all those 90 data.frame objects into a new single one with do.call(rbind, ...) over the list we got from apply.

Ah yes, if you just want to directly insert a single column the other answer rocks as it is simple. My longer answer shows how to grow or construct a data.frame during the sweep of apply.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文