我有一个辅助函数(比如说foo()
),它将在各种数据框上运行,这些数据框可能包含也可能不包含指定的变量.假设我有
library(dplyr)
d1 <- data_frame(taxon=1,model=2,z=3)
d2 <- data_frame(taxon=2,pss=4,z=3)
Run Code Online (Sandbox Code Playgroud)
我想要选择的变量是
vars <- intersect(names(data),c("taxon","model","z"))
Run Code Online (Sandbox Code Playgroud)
也就是说,我想foo(d1)
返回taxon
,model
和z
列,而foo(d2)
回报只是taxon
和z
.
如果foo
包含select(data,c(taxon,model,z))
则foo(d2)
失败(因为d2
不包含model
).如果我使用select(data,-pss)
然后foo(d1)
同样失败.
我知道如果我退出tidyverse(只是返回data[vars]
)该怎么做,但我想知道是否有一个方便的方法来做(1)与某种select()
帮助(tidyselect::select_helpers
)或(2)与tidyeval(其中)我还没有找到时间来围绕让我的头!)
我想获得一个通用公式来排列具有不同列数的数据框。
\n例如,在本例中,数据帧包含“categ_1,categ_2,points_1,points_2”:
\n library(tidyverse)\n set.seed(1)\n nrows <- 20\n df <- tibble(\n other_text = sample(letters,\n nrows, replace = TRUE),\n categ_1 = sample(c("A", "B"), nrows, replace = TRUE),\n categ_2 = sample(c("A", "B"), nrows, replace = TRUE),\n points_1 = sample(20:25, nrows, replace = TRUE),\n points_2 = sample(20:25, nrows, replace = TRUE),\n ) %>%\n rowwise() %>%\n mutate(total = sum(c_across(starts_with("points_")))) %>%\n ungroup()\n
Run Code Online (Sandbox Code Playgroud)\n以及排列的公式:
\ndf %>%\n arrange(\n desc(total),\n categ_1, categ_2,\n desc(points_1), desc(points_2)\n )\n
Run Code Online (Sandbox Code Playgroud)\n但df可以有更多列:“categ_1、categ_2、categ_3、points_1、points_2、points_3”。\n因此,在这种情况下,公式应为:
\ndf %>%\n mutate(\n categ_3 = …
Run Code Online (Sandbox Code Playgroud) 在tidyverse
包中使用选择功能时,我开始收到警告。
例子:
library(dplyr)
set.seed(123)
df = data.frame(
"id" = c(rep("G1", 3), rep("G2", 4), rep("G3", 3)),
"total" = sample.int(n = 10),
"C1" = sample.int(n=10),
"C2" = sample.int(n=10),
"C3" = sample.int(n=10))
cols.to.sum = c("C1", "C2")
df.selected = df %>%
dplyr::select(total, cols.to.sum)
Run Code Online (Sandbox Code Playgroud)
给予:
Note: Using an external vector in selections is ambiguous.
i Use `all_of(cols.to.sum)` instead of `cols.to.sum` to silence this message.
i See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
This message is displayed once per session.
Run Code Online (Sandbox Code Playgroud)
如果我重构为:
df.selected = df %>%
dplyr::select(total, all_of(cols.to.sum))
Run Code Online (Sandbox Code Playgroud)
此行为已从 更改 …
我正在处理一个大数据框,其中有许多我想要分组的列。我想做这样的事情:
output <- df %>%
group_by(starts_with("GEN", ignore.case=TRUE),x,y) %>%
summarize(total=n()) %>%
arrange(desc(total))
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?也许使用 group_by_at 或其他类似的函数?
假设我有一个包含一堆列的数据框,我想在其中进行相同的NA
替换:
dd <- data.frame(x = c(NA, LETTERS[1:4]), a = rep(NA_real_, 5), b = c(1:4, NA))
Run Code Online (Sandbox Code Playgroud)
例如,在上面的数据框中,我想做一些类似 replace_na(dd, where(is.numeric), 0)
替换NA
columnsa
和中的值的操作b
。
我可以
num_cols <- purrr::map_lgl(dd, is.numeric)
r <- as.list(setNames(rep(0, sum(num_cols)), names(dd)[num_cols]))
replace_na(dd, r)
Run Code Online (Sandbox Code Playgroud)
但我正在寻找更整洁/更惯用/更好的东西......
library(tidyverse)
iris %>% as_tibble() %>% select(everything())
#> # A tibble: 150 x 5
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <dbl> <dbl> <dbl> <dbl> <fct>
#> 1 5.1 3.5 1.4 0.2 setosa
#> 2 4.9 3 1.4 0.2 setosa
#> 3 4.7 3.2 1.3 0.2 setosa
#> 4 4.6 3.1 1.5 0.2 setosa
#> 5 5 3.6 1.4 0.2 setosa
#> 6 5.4 3.9 1.7 0.4 setosa
#> 7 4.6 3.4 1.4 0.3 setosa
#> 8 5 3.4 1.5 0.2 …
Run Code Online (Sandbox Code Playgroud) 这是我在包中使用...
参数并tidyselect
选择变量的函数的简化版本:
# this toy function just selects the ... variables
foo <- function(dat = mtcars, ...){
expr <- rlang::expr(c(...))
cols_to_select <- tidyselect::eval_select(expr, data = dat)
dplyr::select(dat, all_of(cols_to_select))
}
Run Code Online (Sandbox Code Playgroud)
这有效: foo(mtcars, cyl)
但是我的实际函数在参数之前有更多前面的...
参数,所有参数都有默认值。如果我使用这些默认值调用我的函数并将值传递给...
.
这就是我想要的 - 假设dat = mtcars
- 但它不起作用:
foo(... = cyl)
错误:名称不得采用
...
或形式..j
。
我可以修改函数或调用以允许直接指定...
吗?
假设我有一个tibble
需要采取多个变量并将它们变为新的多个新变量的位置.
举个例子,这是一个简单的tibble:
tb <- tribble(
~x, ~y1, ~y2, ~y3, ~z,
1,2,4,6,2,
2,1,2,3,3,
3,6,4,2,1
)
Run Code Online (Sandbox Code Playgroud)
我想从名称以"y"开头的每个变量中减去变量z,并将结果变为tb的新变量.另外,假设我不知道我有多少"y"变量.我希望解决方案能够很好地适应tidyverse
/ dplyr
工作流程.
本质上,我不明白如何将多个变量变为多个新变量.我不确定你是否可以mutate
在这个例子中使用?我试过了mutate_if
,但我不认为我正确使用它(我收到错误):
tb %>% mutate_if(starts_with("y"), funs(.-z))
#Error: No tidyselect variables were registered
Run Code Online (Sandbox Code Playgroud)
提前致谢!
我试图了解 tidyverse 设计以及如何使用它进行编程有一段时间了。我试图编写一个使用 tidyselect 语义的函数,我发现tidyselect::eval_select
将数字附加到 lhs 表达式。看到这个语义用于列重命名,这并不奇怪。不幸的是,我用于构建数据结构的函数不需要这种行为,它需要表达式的 lhs 中提供的常规名称(根据需要重复多次)。我还没有设法找出这种行为的来源;它似乎是一个,make.unique
但我找不到它的实现位置。如果你知道,我很想学习,如果没有,解决我的问题不应该依赖于它。我想要的只是 lhs 名称没有附加数字,如示例所示:
library(tidyverse)
# Data
data <- mtcars[, 8:11]
# Example
data %>%
tidyselect::eval_select(rlang::expr(c(foo = 1, bar = c(2:4), foobar = c(1, "am", "gear", "carb"))), .)
#> foo bar1 bar2 bar3 foobar1 foobar2 foobar3 foobar4
#> 1 2 3 4 1 2 3 4
# Function
test <- function(.data, ...) {
loc <- tidyselect::eval_select(rlang::expr(c(...)), .data)
names <- names(.data)
list(names(loc), names[loc])
}
data %>%
test(foo = 1, bar …
Run Code Online (Sandbox Code Playgroud) 我尝试使用read_csv
from{readr}
将文件读入 R。为了演示我的真正问题,我首先CSV
将参数重置为 5(默认为 1000)guess_max
library(readr)\nformals(read_csv)$guess_max <- 5\n
Run Code Online (Sandbox Code Playgroud)\n并以较小的文字数据为例:
\ncsv <- I(\n"ID, Col1, Col2, VarA, VarB, VarC\n1, NA, NA, NA, NA, NA\n2, NA, NA, NA, NA, NA\n3, NA, NA, NA, NA, NA\n4, NA, NA, NA, NA, NA\n5, 0, 1, x, y, z\n6, NA, NA, NA, NA, NA")\n\nread_csv(csv)\n\n# # A tibble: 6 \xc3\x97 6\n# ID Col1 Col2 VarA VarB VarC \n# <dbl> <lgl> <lgl> <lgl> <lgl> <lgl>\n# 1 1 NA NA NA …
Run Code Online (Sandbox Code Playgroud)