在研究中为几个人运行R中的脚本

时间:2016-09-08 16:03:55

标签: r

我是硕士生的动物行为学生,非常初学R.我正在为我的论文做统计,并决定在我求助于PSPP之前试一试R,经过一个小小的介绍当然,我使用的是R Studio。

我写了一个非常基本的脚本

  1. 从csv的51个人中导入数据。文件,还导入一个csv。用于存储结果的文件。
  2. 使用来自一个人的数据创建子集,然后根据数据进行假设,运行二项式检验并确定假设是否被拒绝。假设,二项式检验的p值和每个人的假设拒绝/接受都存储在结果文件中。
  3. 当我为每个人运行脚本时,脚本功能完全正常。我提前为代码的质量差而道歉,但如果你想看一下,这里是一个人的脚本:

    ## Import data and results file
    odor_behavior <- read.csv("odor_behavior.csv")
    percalf_binomial_odor_results <- read.csv("percalf_binomial_odor_results.csv")
    
    # Create binomial dataset per calf (example here: 958)
    pref958 <- subset(odor_behavior, Calf_ID == 958, c("Preference"), drop=FALSE)
    
    # Count the number of testing sessions for this calf
    n958 <- nrow(pref958)
    
    # Calculate how many times a suckling behavior appears (Control=1 or Modified=3).
    mat958 <- as.matrix(pref958)
    fmat958 <- factor(mat958,levels=c(1,3),ordered=TRUE)
    fpref958 <- table(fmat958)
    data958 <- as.data.frame(fpref958)
    
    # Hypothesize a preference according to the observations and save it. 
    # Also, save variables for the binomial test.
    ## Find the row in which to store the results
    row958<- which(percalf_binomial_odor_results$Calf_ID == 958)
    ## Decide the hypothesis. 
      if (data958[1,2] > data958[2,2]) {
        x958 <- data958[1,2]
        percalf_binomial_odor_results[row958,c("H_preference")] <- "Control"
      } else if (data958[1,2] < data958[2,2]) {
        x958 <- data958[2,2]
        percalf_binomial_odor_results[row958,c("H_preference")] <- "Odor"
      } else if (data958[1,2] == data958[2,2]) {
        x958 <- data958[1,2]
        percalf_binomial_odor_results[row958,c("H_preference")] <- "Either"
      } else {print("Check your data, Maria!")
      }
    
    
    # Run binomial test
    binom.test (x=x958, n=n958, p=0.5, conf.level = 0.95)
    
    # Save the p.value and decide whether the hypothesized preference is real or not
    pbin958 <- binom.test (x=x958, n=n958, p=0.5, conf.level = 0.95)$p.value
    percalf_binomial_odor_results[row958,c("Bin_odor_pvalue")] <- pbin958
      if (pbin958 <0.05) {
        percalf_binomial_odor_results[row958,c("Real_preference")] <- "Yes"
      } else {
        percalf_binomial_odor_results[row958,c("Real_preference")] <- "No"
      }
    

    如上所述,当我为每个人重复脚本时,通过复制粘贴代码并手动更改&#34; Calf_ID&#34;五十次。

    问题:脚本是否可以为每个人自行运行?我尝试将所有51&#34; Calf_ID&#34;放在矩阵中,然后将脚本放在一个函数中,该函数使用矩阵中的元素来遍历每个人。

    Lapply 返回正确的结果,但仅限于假设是否被接受/拒绝(即脚本的最后一部分),这让我认为该脚本确实适用于所有51个人。但是,在此过程中没有结果存储在相应的文件中(很可能是因为我首先做错了)。当我进行手动复制 - 粘贴/编辑程序时,所有结果(假设,p值和每个人的假设结果)都正确存储在结果文件中。

    我能通过复制粘贴方法获得我的结果;这只是一个效率问题,因为现在我有51个人,但是当他们有一千个时,他们做了什么?知道如何让它发挥作用真是太棒了!

    修改
    根据评论中的要求,以下是结果(在运行个人958的脚本之后)

      

    dput(头(odor_behavior)):
      结构(列表(Calf_ID = c(958L,958L,958L,958L,958L,958L),偏好= c(1L,1L,3L,1L,1L,3L)),. Name = c(&#34; Calf_ID&# 34;,&#34;偏好&#34;),row.names = c(NA,6L),class =&#34; data.frame&#34;)

      

    dput(头(percalf_binomial_odor_results)):
      结构(列表(Calf_ID = c(958L,7015L,7017L,959L,7018L,7019L),   H_preference = c(&#34; Control&#34;,NA,NA,NA,NA,NA),Bin_odor_pvalue = c(0.453125,NA,NA,NA,NA,NA),Real_preference = c(&#34; No& #34;,NA,NA,NA,NA,NA)),. Name = c(&#34; Calf_ID&#34;,&#34; H_preference&#34;,&#34; Bin_odor_pvalue&#34;,&# 34; Real_preference&#34;),row.names = c(NA,6L),class =&#34; data.frame&#34;)

    更新
    以下是基于为初始脚本提供的@alexis_laz答案的同一主题的另一个示例。在这种情况下,我正在导入3列(Calf_ID,Control_time,Odor_time)的数据集,其中包括给定Calf ID的几个控制和气味时间测量值(如初始示例中的首选项)。该脚本尝试为每个Calf_ID对Control_time - Odor_time对进行Wilcoxon符号秩检验。以下是脚本的外观:

        ### Import data and load library with test
    odor_times <- read.csv("odor_times.csv")
    library(coin)
    
    ### Create a function that examines suckling preference
    prefanalysis <- function(Control_time, Odor_time)
    {
      sessions <- length(Control_time)
    
      #Run a Wilcoxon signed rank test. Set y ~ x as control and odor, 
      mypvalue <- pvalue(wilcoxsign_test(Control_time ~ Odor_time))
      myzvalue <- statistic(wilcoxsign_test(Control_time ~ Odor_time))
    
      #Decide if there is a true difference in suckling times according to p value, and save it
      true_diff <- if(mypvalue < 0.05) "Yes" else "No"
    
      # Create a data frame with hypothesis, p value and real preference
      data.frame(sessions, myzvalue, mypvalue, true_diff, stringsAsFactors = FALSE)
    }
    
    ### Run the function for all calves, with preference depending on calf ID. Save results.
    results <- as.data.frame(do.call(data.frame, aggregate(cbind(Control_time, Odor_time) ~ Calf_ID, odor_times, prefanalysis)))
    

    在这种情况下,我收到以下错误:

         Error in eval(expr, envir, enclos) : 
      argument "Odor_time" is missing, with no default
    

    当重新运行Debug时,我可以看到脚本开始正确读取第一个人的Control_time(即具有特定Calf_ID的行)。然而,似乎无法对Odor_time做同样的事情。我不能(为了我的生活)看到我做错了什么。

1 个答案:

答案 0 :(得分:4)

似乎您将计算应用于&#34;偏好&#34;按每个&#34; Calf_ID&#34;分组。我们可以使用R的分组函数,而不是为每个id重复子集odor_behavior$Preference,首先,构建一个在给定适当输入的情况下执行所有工作的函数。

我试图在一个函数中简化你的脚本 - 希望我没有错过任何难以容纳的细节:

ff = function(pref)
{
    fx = factor(pref, levels = c(1L, 3L), labels = c("Control", "Odor"))
    tab = table(fx)

    p = binom.test(max(tab), length(pref), p = 0.5, conf.level = 0.95)$p.value

    real_pref = if(p < 0.05) "yes" else "no"
    H_pref = if(tab["Control"] == tab["Odor"]) "Either" else names(which.max(tab))

    data.frame(p = p, real_pref = real_pref, H_pref = H_pref, stringsAsFactors = FALSE)
}

然后,将它应用于所有&#34; Calf_ID&#34;个体:

do.call(data.frame, aggregate(pref ~ ID, dat, ff))
#   ID     pref.p pref.real_pref pref.H_pref
#1   1 0.07295139             no     Control
#2   2  0.1689778             no     Control
#3   3  0.8919232             no        Odor
#4   4  0.6029232             no        Odor
#5   5          1             no     Control
#6   6  0.7659918             no     Control
#7   7          1             no        Odor
#8   8   0.889884             no     Control
#9   9          1             no      Either
#10 10  0.5758493             no     Control

其中dat是:

set.seed(1821)
dat = data.frame(ID = sample(10, 500, TRUE), pref = sample(c(1L, 3L), 500, TRUE))