【问题标题】:Create a new variable that is the average of one variable conditional on two other variables (and maintain all other variables in the data set)创建一个新变量,它是一个变量以其他两个变量为条件的平均值(并维护数据集中的所有其他变量)
【发布时间】:2019-08-16 19:07:05
【问题描述】:

这是我正在处理的数据集中的一个(缩短的)样本。该样本代表来自具有 2 个会话 (session_number) 的实验的数据,在每个会话中,参与者完成了 5 次手握练习试验 (trial_number)(因此,总共 10 个;2 * 5 = 10)。 5 次试验中的每一次都有 3 次握力观察 (percent_of_maximum)。我想获得 10 次试验中每一次的这 3 次观察的平均值(下面,我称之为 mean_by_trial)。

最后,这就是我所坚持的,我想输出一个 20 行长的数据集(每个唯一试验一行,每个参与者有 2 个参与者和 10 个试验;2 * 10 = 20 ),并且保留所有其他变量。对于每个唯一的Participanttrial_numbersession_number,所有其他变量(在示例中为:placebosupportpersonalityperceived_difficulty)将是相同的(参见示例数据集如下)。

我已经尝试过使用ddply,这几乎是我想要的,但是新数据集不包含数据集中的其他变量(new_dat 仅包含trial_numbersession_number、@ 987654336@ 和新的mean_by_trial 变量)。如何维护其他变量?

#create sample data frame
dat <- data.frame(
  Participant = rep(1:2, each = 30),
  placebo = c(replicate(15, "placebo"), replicate(15, "control"), replicate(15, "control"), replicate(15, "placebo")),
  support = rep(sort(rep(c("support", "control"), 3)), 10),
  personality = c(replicate(30, "nice"), replicate(30, "naughty")),
  session_number = c(rep(1:2, each = 15), rep(1:2, each = 15)),
  trial_number = c(rep(1:5, each = 3), rep(1:5, each = 3), rep(1:5, each = 3), rep(1:5, each = 3)),
  percent_of_maximum = runif(60, min = 0, max = 100),
  perceived_difficulty = runif(60, min = 50, max = 100)
)

#this is what I have tried so far
library(plyr)
new_dat <- ddply(dat, .(trial_number, session_number, Participant), summarise, mean_by_trial = mean(percent_of_maximum), .drop = FALSE)

我希望new_dat 包含dat 中的所有变量,以及mean_by_trial 变量。谢谢!

【问题讨论】:

    标签: r dplyr plyr


    【解决方案1】:

    我们可以使用mutate而不是summarise在数据集中创建一列,然后执行slice

    library(dplyr)
    out <- ddply(dat, .(trial_number, session_number, Participant), 
       plyr::mutate, mean_by_trial = mean(percent_of_maximum), .drop = FALSE)
    out %>%
           group_by(trial_number, session_number, Participant) %>%
           slice(1)
    

    如果我们使用dplyr,那么这都可以在一个链中

    newdat <- dat %>% 
                group_by(trial_number, session_number, Participant) %>%
                mutate(mean_by_trial = mean(percent_of_maximum)) %>%
                slice(1)
    head(newdat)
    # A tibble: 6 x 9
    # Groups:   trial_number, session_number, Participant [6]
      Participant placebo support personality session_number trial_number percent_of_maximum perceived_difficulty mean_by_trial
    #        <int> <fct>   <fct>   <fct>                <int>        <int>              <dbl>                <dbl>         <dbl>
    #1           1 placebo control nice                     1            1               71.5                 95.5          73.9
    #2           2 control control naughty                  1            1               38.9                 63.8          67.7
    #3           1 control support nice                     2            1               97.1                 54.2          68.4
    #4           2 placebo support naughty                  2            1               62.9                 86.2          40.4
    #5           1 placebo support nice                     1            2               49.0                 95.8          65.7
    #6           2 control support naughty                  1            2               80.9                 74.6          68.3
    

    【讨论】:

      【解决方案2】:

      这是tidyverse 的答案。首先你想group_by 感兴趣的变量。然后使用mutate 在新列中计算所需的平均值。

      由于新均值列中的值将在变量中重复,请使用 distinct 函数保留唯一行。换句话说,为Participantsession_numbertrial_number 的每个组合选择一行。

      这就是答案 (https://*.com/a/39092166/9941764) 提供于:R - dplyr Summarize and Retain Other Columns

      new_dat <- dat %>%
          group_by(Participant, session_number, trial_number) %>%
          mutate(mean = mean(percent_of_maximum)) %>% 
          distinct(mean, .keep_all = TRUE)
      

      【讨论】: