如何将基本 R 语法转换为 dplyr/tidyverse

How to convert base R syntax into dplyr/tidyverse

提问人:R_studio_user11 提问时间:11/14/2023 最后编辑:R_studio_user11 更新时间:11/15/2023 访问量:76

问:

我想将这个条件子集语句转换为使用 dplyr 语法的语句,使用括号索引。

newdat = dat[ps >= min(ps[dat$treat == 1]) & ps <= max(ps[dat$treat == 0]), ]

我尝试了以下方法:

newdat = dat %>% filter(ifelse(treat == 1, ps >= min(ps), ps <= max(ps)))

但它没有返回子集。

r dplyr tidyverse

评论

2赞 Sweepy Dodo 11/14/2023
newdat <- dat %>% filter(ps >= min(ps[treat == 1]), ps <= max(ps[treat == 0]))
0赞 R_studio_user11 11/14/2023
谢谢,有趣的是,仍然需要使用括号。
0赞 Mark 11/14/2023
@R_studio_user11 ps 似乎是一个向量,那么你期待什么?
0赞 R_studio_user11 11/14/2023
@Mark我认为在使用 tidyverse 表示法时,不使用括号或美元符号或基数 R 的表示法
0赞 Mark 11/14/2023
我理解你为什么会有这种印象,但我认为 tidyverse 仍然使用单括号来表示事情

答:

0赞 G. Grothendieck 11/15/2023 #1

1)我们可以使用filter/between:

# test data
dat <- data.frame(ps = seq(-1.1, 1.1, .2), treat = rep(0:1, 6))

# soln from question
ps <- dat$ps  # need this for soln in question to make sense
newdat = dat[ps >= min(ps[dat$treat == 1]) & ps <= max(ps[dat$treat == 0]), ]
rownames(newdat) <- NULL # need this to make solutions identical

# tidyverse
library(dplyr)
newdat2 <- dat %>%
  filter(between(ps, min(ps[treat == 1]), max(ps[treat == 0])))

# compare
identical(newdat, newdat2)
## [1] TRUE

2) 这是代码方面较长的变体:

newdat3 <- dat %>%
  filter(between(ps,
    filter(., treat == 1) %>% slice_min(ps) %>% pull(ps),
    filter(., treat == 0) %>% slice_max(ps) %>% pull(ps)
  )
)

# compare
identical(newdat, newdat3)
## [1] TRUE