如何在管道末端运行函数?

问题描述 投票:0回答:7

此代码从数据框中的两个不同列生成一个句子

library(dplyr); library(tibble); library(magrittr)

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) -> 
  df

paste0(df$car, " (", df$mpg, ")", collapse = ", ")

# "Mazda RX4 Wag (21), Hornet Sportabout (18.7), Merc 280 (19.2), Dodge Challenger (15.5), Merc 450SLC (15.2)"

但不是让

paste0(df$car, " (", df$mpg, ")", collapse = ", ")
在独立线路上运行,我怎样才能让它在管道末端运行,如下所示(这会引发写入的错误):

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>%
  paste0(df$car, " (", df$mpg, ")", collapse = ", ")
r dataframe pipe tibble
7个回答
13
投票

with()
适用于此:

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>% 
  with(paste0(car, " (", mpg, ")", collapse = ","))

另一种可能性是用以下方式结束管道:

... %>% 
   mutate(word = glue("{car} ({mpg})")) %>% 
   pull(word) %>% 
   paste0(collapse =", ")

10
投票

这是基本 R 方法。

> sprintf('%s (%s)', rownames(mtcars), mtcars$mpg) |> sample(5) |> toString()
[1] "Chrysler Imperial (14.7), Hornet Sportabout (18.7), Mazda RX4 (21), Pontiac Firebird (19.2), Merc 280 (19.2)"

> transform(mtcars, car=rownames(mtcars)) |> 
+   subset(car %in% sample(car, 5)) |> 
+   with(sprintf('%s (%s)', car, mpg)) |> 
+   toString()
[1] "Mazda RX4 (21), Hornet Sportabout (18.7), Merc 280 (19.2), Chrysler Imperial (14.7), Pontiac Firebird (19.2)"

9
投票

glue::glue_data()
是专门为此用例构建的简洁解决方案:

library(dplyr)
library(tibble)
library(glue)
library(stringr)

mtcars |> 
  rownames_to_column("car") |> 
  sample_n(5) |> 
  glue_data("{car} ({mpg})") |> 
  str_flatten_comma()
#> [1] "Merc 230 (22.8), Hornet 4 Drive (21.4), Merc 280 (19.2), Camaro Z28 (13.3), Lotus Europa (30.4)"

创建于 2024-04-17,使用 reprex v2.1.0


7
投票

另外三个类似于

with()
的解决方案:

大括号中的点表示法

library(dplyr)
library(tibble)

set.seed(42)

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>% 
  { paste0(.$car, " (", .$mpg, ")", collapse = ", ") }
#> [1] "Chrysler Imperial (14.7), Hornet Sportabout (18.7), Mazda RX4 (21), Pontiac Firebird (19.2), Merc 280 (19.2)"

创建于 2024-04-17,使用 reprex v2.1.0

匿名函数

library(dplyr)
library(tibble)

set.seed(42)

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>%
  {\(x) paste0(x$car, " (", x$mpg, ")", collapse = ", ")}()
#> [1] "Chrysler Imperial (14.7), Hornet Sportabout (18.7), Mazda RX4 (21), Pontiac Firebird (19.2), Merc 280 (19.2)"

创建于 2024-04-17,使用 reprex v2.1.0

自定义功能

library(dplyr)
library(tibble)

set.seed(42)

my_fun <- function(x) paste0(x$car, " (", x$mpg, ")", collapse = ", ")

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>%
  my_fun()
#> [1] "Chrysler Imperial (14.7), Hornet Sportabout (18.7), Mazda RX4 (21), Pontiac Firebird (19.2), Merc 280 (19.2)"

创建于 2024-04-17,使用 reprex v2.1.0


7
投票

使用

magrittr
展览管
%$%
stringr::str_glue
的替代方案:

mtcars %>% 
  head() %>% 
  rownames_to_column(var = "car") %$%
  str_glue("{car} ({mpg})") %>% 
  str_flatten_comma()

输出:

[1] "Mazda RX4 (21), Mazda RX4 Wag (21), Datsun 710 (22.8), Hornet 4 Drive (21.4), Hornet Sportabout (18.7), Valiant (18.1)"

7
投票

我会提供这个选项:

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>%
  transmute(tmp = paste0(car, " (", mpg, ")")) %>% 
  pull %>% 
  paste0(collapse = ", ")

[1] "Fiat 128 (32.4), Merc 280C (17.8), Valiant (18.1), Lotus Europa (30.4), Cadillac Fleetwood (10.4)"

已附上

如果您需要存储

df
,如您的问题所示,您可以使用
%T>%
包中的
magrittr
assign()
调用:

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %T>%
  assign("df", ., envir = .GlobalEnv) %>% 
  transmute(tmp = paste0(car, " (", mpg, ")")) %>% 
  pull %>% 
  paste0(collapse = ", ")

4
投票

如果您需要捕获结果

https://stackoverflow.com/a/78341333/11732165 存储

df
而许多其他人则不存储,您可能会发现后者更自然:

mtcars %>% 
  rownames_to_column(var = "car") %>%
  sample_n(5) %>%
  `<-`(df, .) %>%
  paste0(.$car, " (", .$mpg, ")", collapse = ", ")

因为它只是通过管道传输到标准赋值函数。

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