【问题标题】:randomly select values from each row across columns in a data.frame and average them in R从 data.frame 中各列的每一行中随机选择值并在 R 中平均它们
【发布时间】:2012-06-14 07:53:08
【问题描述】:

这个问题与我在这里提出的前一个问题相似:randomly sum values from rows and assign them to 2 columns in R

由于我在使用 R 时遇到困难,所以这个问题既是关于编程的,也是关于统计的。我对两者都很陌生。

我有一个 data.frame,在一列中有 219 个主题。其余的列是 7,在每一行中,我都有一个数字,代表该特定受试者在暴露于两种实验条件时的响应时间差异。

数据是这样的(我用的是head函数,不然会太长):

    > head(RTsdiff)
      subject   block3diff   block4diff   block5diff   block6diff   block7diff
    1   40002  0.076961798  0.046067460 -0.027012048  0.017920261  0.002660317
    2   40004  0.037558511 -0.016535211 -0.044306743 -0.011541667  0.044422892
    3   40006 -0.017063123 -0.031156150 -0.084003876 -0.070227149 -0.113382784
    4   40008 -0.015204017 -0.009954545 -0.004082353  0.006327839  0.022335271
    5   40009  0.006055829 -0.045376437 -0.002725572  0.016443182  0.032848128
    6   40010 -0.003017857 -0.034398268 -0.034476491  0.014158824 -0.036592982
       block8diff    block9dif
    1  0.03652273  0.037306173
    2 -0.08032784 -0.150682051
    3 -0.09724864 -0.060338684
    4 -0.04783333  0.006539326 
    5 -0.01459465 -0.067916667
    6 -0.01868126 -0.034409584

我需要的是一个代码,它将对每个主题(即每一行)采样 3 或 4 个值,将它们平均,然后将它们添加到新向量(称为 half1)中。向量 half2 应该具有在第一次尝试中未采样的值的平均值。

所以,假设我想要创建的 data.frame 被称为“RTshalves”,我需要第一列是 RTsdiff 中主题的同一列,第二列必须在第一行中具有随机数的平均值选择的值对应于第一个主题,并且第二列必须具有第一个样本中未选择的第一个主题的值的平均值。第 2 列和第 3 列的第二行应该具有相同的信息,但这次是针对主题 2(即我的 data.frame 中的主题 40004)等,直到达到 219 个主题。

假设第一个样本随机选择了对象 1 的 3 个值(block3diff、block5diff 和 block9diff),因此 block4diff、block6diff、block7diff 和 block8diff 的值将自动对应另一半。然后,我希望看到的(仅考虑 219 行中的第一行)是:

   Subject     Half1       Half2 
    40002   0.02908531   0.02579269

如果有人对此背后的统计数据感兴趣,我正在尝试进行半信度测试以检查测试的一致性。基本原理是,如果 RT 平均值的差异是效果的可靠估计量,那么一个参与者的一半块的差异应该与另一半块的差异相关。

非常感谢您的帮助。 提前致谢。

【问题讨论】:

    标签: r random dataframe reliability mean


    【解决方案1】:

    half1 很简单:编写你自己的函数来对每一行做你想做的事(作为一个向量),然后 apply 它到行:

    eachrow <- function(x) {
       mean(sample(x,2))
    }
    RTsdiff$half1 <- apply(eachrow,1,RTsdiff)
    

    要获得 half2,您可能需要同时进行。 ddply 可能是最简单的(让 by 参数成为您的主题变量以获取每一行)。像这样:

    RTsdiff <- data.frame(subject=seq(6))
    RTsdiff <- cbind( RTsdiff, matrix(runif(6*8),ncol=8) )
    
    library(plyr)
    eachrow <- function(x,n=3) {
      x <- as.numeric(x[,2:ncol(x)]) # eliminate the ID column to make things easier, make a vector
      s <- seq(length(x))
      ones <- sample(s,n) # get ids for half1
      twos <- !(s %in% ones) # get ids for half2
      data.frame( half1=mean(x[ones]), half2=mean(x[twos]) )
    }
    ddply( RTsdiff, .(subject), eachrow)
    
      subject     half1     half2
    1       1 0.4700982 0.5350610
    2       2 0.6173469 0.5351995
    3       3 0.2245246 0.6807482
    4       4 0.6330649 0.6316353
    5       5 0.6388060 0.6629077
    6       6 0.4652086 0.5073034
    

    有很多更优雅的方法可以做到这一点。特别是,我使用了ddply,因为它能够轻松输出data.frames,这样我就可以从函数中输出half1half2,并在最后将它们很好地组合在一起,但ddply 需要数据。帧作为输入,所以有一些轻微的诡计首先将其输出到向量。为 sapply 提供转置的 data.frame 可能会更简单。

    【讨论】:

    • 我认为为了满足 OP 的愿望,你的 eachrow 函数应该排除第一列。如果我是对的,也许mean(sample(x[-1],2)) 就足够了。
    • 您的意思是排除block3diff?那不是我的阅读,但如果你指出这是很容易完成的。
    • 感谢您的回答 gsk3,但我对此有点困惑。首先,你为什么要定义函数 eachrow() 两次? (在您答案的第一段代码和第二段代码中)。其次,你为什么要重新定义 RTsdiff,也是两次,并覆盖我拥有的数据。你这样做是为了有一个示例 data.frame 吗?第三,如果参数 n=3,那么“ones”中采样的数字将始终为 3,而“twos”中采样的对象将始终为 4。我需要随机抽样(即有时 3 到“一”,有时 4 到“一”)。非常感谢您的帮助。
    • 1) 第一个是一个更简单的示例,用于说明apply 系列函数的工作原理。它与第二个关系不大。 2)您没有提供示例数据集,所以我创建了一个。以后请使用dput,以便重新创建您的示例。 3)很容易改变。只需在采样的eachrow 函数中添加一行:n &lt;- sample(c(3,4))
    • 感谢您的澄清 gsk3。我实际上已经尝试过 n=sample(c(3:4)) 但我试图在定义 eachrow 函数的参数时在行中指定它(这给了我一个错误)。我现在按照您的建议所做的是在参数定义中删除 n 的值 3 (所以它看起来像 eachfunction(x) 然后我将 n 定义为 sample(c(3:4)) 我得到的结果出的相关性与我的预期非常不同,所以这让我怀疑我做对了,但如果代码做了我在问题中描述的那样,那么我想我有非常奇特的结果:)
    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多