【问题标题】:How can I make row_number() and quosures work together in an R function?如何使 row_number() 和 quosures 在 R 函数中一起工作?
【发布时间】:2020-02-22 12:33:42
【问题描述】:

我有一个参与者内部设计的结果,其中包含每个试验的时间序列信息。我想重新调整一些排列测试的条件。我需要编写一个函数,这就是我遇到问题的地方。

我的数据看起来像这样:

library(tidyverse) 

sampel <- expand.grid(s0 = 1:5, r0 = 1:12)
sampel <- sampel %>% mutate(c0 = rep(c('A', 'B'), 30))

sampel <- sampel %>% 
  group_by(s0, c0, r0) %>% 
  nest() %>% 
  mutate(t0 = map(data, function(t) seq(1:8)), v0 = map(data, function(v) seq(from = 0, by = runif(1), length.out = 8))) %>% 
  unnest(cols = c(data, t0, v0)) %>% 
  ungroup() %>% 
  mutate(s0 = paste('s', s0, sep = ''))

head(sampel, n = 12)

(如果您有任何指示我可以如何以更好的方式展示此示例,我也将不胜感激)

因此,添加一些背景信息,这是一项学科内研究的结果。 s0 代表参与者,c0 代表条件,r0 代表试验编号(运行)。 t0 是一个时间点,v0 是该时间点的感兴趣值。

我正在尝试重新调整参与者内部的条件

resampledSampel <- 
  sampel %>% 
  group_by(s0, r0, c0) %>% 
  nest() %>% 
  group_by(s0) %>% 
  mutate(c1 = c0[sample(row_number())])


resampledSampel %>% 
  head(n = 12)

这可以正常工作,但是当我尝试创建一个函数时:

resample_within <- function(df, subject, trial, condition) {

  subject <- enquo(subject)
  trial <- enquo(trial) 
  condition <- enquo(condition)

  resampled <- 
    df %>% 
    group_by(!!subject, !!trial, !!condition) %>%
    nest() %>% 
    group_by(!!subject) %>% 
    mutate(condition = !!condition[sample(row_number())]) %>% 
    unnest(data)
  return(resampled)

}

resample_within(sampel, s0, r0, c0) 

抛出错误:

Error: row_number() should only be called in a data context
Run `rlang::last_error()` to see where the error occurred.
In addition: Warning message:
Subsetting quosures with `[` is deprecated as of rlang 0.4.0
Please use `quo_get_expr()` instead.
This warning is displayed once per session. 

知道如何在函数中使用mutate(condition = !!condition[sample(row_number())]) 吗?或者我如何在没有 dplyr 的情况下完成这一切(这让我意识到我可能过于依赖 dplyr 了……)

提前谢谢你。而且,如果我提出问题的方式不理想,我也提前道歉(我也很乐意就如何更好地制定堆栈交换问题提出任何指示。例如,我似乎无法弄清楚如何显示数据结构)

【问题讨论】:

    标签: r dplyr permutation


    【解决方案1】:

    第一个问题非常好!

    这实际上只是运算符优先级的问题。当您调用!!condition[sample(row_number())] 时,它被解释为!!(condition[sample(row_number())]),即您尝试将quosure 子集化然后应用双爆炸,但您意思是(!!condition)[sample(row_number())],即,您想对双键的 result 进行子集化。因此,只需应用括号来固定评估顺序,它就可以按预期工作:

    resample_within <- function(df, subject, trial, condition) {
    
      subject <- enquo(subject)
      trial <- enquo(trial) 
      condition <- enquo(condition)
    
      resampled <- 
        df %>% 
        group_by(!!subject, !!trial, !!condition) %>%
        nest() %>% 
        group_by(!!subject) %>% 
        mutate(condition = (!!condition)[sample(row_number())]) %>% 
        unnest(data)
      return(resampled)
    
    }
    

    现在:

    resample_within(sampel, s0, r0, c0) 
    #> # A tibble: 480 x 6
    #> # Groups:   s0 [5]
    #>    s0       r0 c0       t0    v0 condition
    #>    <chr> <int> <chr> <int> <dbl> <chr>    
    #>  1 s1        1 A         1 0     B        
    #>  2 s1        1 A         2 0.981 B        
    #>  3 s1        1 A         3 1.96  B        
    #>  4 s1        1 A         4 2.94  B        
    #>  5 s1        1 A         5 3.93  B        
    #>  6 s1        1 A         6 4.91  B        
    #>  7 s1        1 A         7 5.89  B        
    #>  8 s1        1 A         8 6.87  B        
    #>  9 s2        1 B         1 0     A        
    #> 10 s2        1 B         2 0.976 A        
    #> # ... with 470 more rows
    

    【讨论】:

      【解决方案2】:

      我们可以使用 curly-curly ({{}}) 运算符

      library(dplyr)
      library(tidyr)
      resample_within <- function(df, subject, trial, condition) {
      
      
      
          df %>% 
          group_by({{subject}}, {{trial}}, {{condition}}) %>%
          nest() %>% 
          group_by({{subject}}) %>% 
          mutate(condition = ({{condition}})[sample(row_number())]) %>% 
          unnest(data)
      
      
      }
      
      resample_within(sampel, s0, r0, c0) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-18
        • 1970-01-01
        • 2018-11-26
        相关资源
        最近更新 更多