如何使row_number()和quosures在R函数中一起工作?

问题描述 投票:1回答:2

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

我的数据看起来像这样:

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
2个回答
1
投票

非常好的第一个问题!

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

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


0
投票
我们可以使用curl-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)

© www.soinside.com 2019 - 2024. All rights reserved.