Reputation: 21204
Read these two posts already:
I'm using Shiny input$selector and if the user has selected a particular value, I want my dataframe to be different than otherwise.
Here's a chain:
filtered_funnel <- reactive({
lastmonth_funnel %>%
filter(input$channel == "All" | Channel == input$channel) %>%
filter(input$promo == "All" | Promo == input$promo) %>%
## HERE IS WHERE I'M STRUGGLING
{if(input$promo != "none") select(., c("Channel", "Promo", "ShippingDetails", "Checkout", "Transactions"))} %>%
gather(Funnel, Sessions, -Channel, -Promo) %>%
group_by(Channel, Promo, Funnel) %>%
summarise(Sessions = sum(Sessions))
})
If the user input does not equal "none" I would like to select variables "Channel", "Promo", "ShippingDetails", "Checkout" and "Transactions".
I tried a few variations of the problem line above but kept getting errors:
When I tried this within the pipe chain
{if(input$promo != "none") select(., c("Channel", "Promo", "ShippingDetails", "Checkout", "Transactions"))} %>%
I received this error:
Warning: Error in : All select() inputs must resolve to integer column positions. The following do not: * c("Channel", "Promo", "ShippingDetails", "Checkout", "Transactions")
I also tried:
{if(input$promo != "none") select(., c(Channel, Promo, ShippingDetails, Checkout:Transactions))} %>%
This actually runs till I select "none" in the input, in which case I get
Error in : is.character(x) is not TRUE
I got the same error when I tried this:
{ifelse(input$promo != "none", select(., c(Channel, Promo, ShippingDetails, Checkout:Transactions)), .)} %>%
How can I nest in a dplyr pipe chain a select statement that says if input$promo != "none" then select Channel, Promo, ShippingDetails, Checkout:Transactions from the passed object in the pipe?
-- Here's dput of the randomly generated data--
> dput(lastmonth_funnel)
structure(list(Channel = c("Facebook", "Youtube", "SEM", "Organic",
"Direct", "Email", "Facebook", "Youtube", "SEM", "Organic", "Direct",
"Email", "Facebook", "Youtube", "SEM", "Organic", "Direct", "Email",
"Facebook", "Youtube", "SEM", "Organic", "Direct", "Email", "Facebook",
"Youtube", "SEM", "Organic", "Direct", "Email"), Promo = c("none",
"none", "none", "none", "none", "none", "banannas", "banannas",
"banannas", "banannas", "banannas", "banannas", "carrots", "carrots",
"carrots", "carrots", "carrots", "carrots", "pears", "pears",
"pears", "pears", "pears", "pears", "apples", "apples", "apples",
"apples", "apples", "apples"), Sessions = c(6587, 3015, 6316,
11219, 8117, 6473, 12464, 14032, 14318, 17535, 16219, 7838, 10685,
12040, 19907, 13694, 6187, 16784, 21425, 18890, 24891, 16251,
16977, 25206, 28573, 18704, 29178, 22069, 39687, 53734), AddToCart = c(279,
4955, 5636, 8991, 15530, 18374, 9431, 5980, 4852, 5412, 4114,
1782, 370, 3208, 6311, 9760, 7428, 6792, 3500, 5446, 1507, 783,
2032, 833, 397, 2760, 5784, 9810, 13274, 14470), Registrations = c(194,
3210, 3573, 6067, 10305, 12653, 6564, 3874, 3076, 3652, 2730,
1227, 257, 2078, 4001, 6586, 4929, 4677, 2436, 3528, 955, 528,
1348, 573, 276, 1788, 3667, 6620, 8808, 9964), ShippingDetails = c(134,
2235, 2593, 4266, 7408, 9244, 4557, 2698, 2232, 2568, 1962, 896,
178, 1447, 2904, 4631, 3543, 3417, 1691, 2457, 693, 371, 969,
418, 191, 1245, 2661, 4655, 6332, 7280), Checkout = c(90, 1436,
1792, 2864, 4672, 5666, 3078, 1734, 1543, 1724, 1237, 549, 120,
930, 2007, 3109, 2234, 2094, 1142, 1579, 479, 249, 611, 256,
129, 800, 1839, 3125, 3993, 4462), Transactions = c(59, 937,
1192, 1819, 2602, 2926, 2039, 1132, 1026, 1095, 689, 283, 79,
607, 1335, 1975, 1244, 1081, 756, 1031, 318, 158, 340, 132, 85,
522, 1223, 1985, 2224, 2304)), class = "data.frame", row.names = c(NA,
-30L), .Names = c("Channel", "Promo", "Sessions", "AddToCart",
"Registrations", "ShippingDetails", "Checkout", "Transactions"
))
Upvotes: 5
Views: 4708
Reputation: 35187
You need to make sure that your statement between {
returns a data.frame regardless of the condition. So you need an else .
.
cond <- FALSE
mtcars %>%
group_by(cyl) %>%
{ if (cond) filter(., am == 1) else . } %>%
summarise(m = mean(wt))
Works fine with TRUE
or FALSE
.
(Also note that a simple example like this really makes the question a lot more easy to grasp.)
With R's native pipe, you can use this somewhat akward anonomous function:
mtcars |>
group_by(cyl) |>
(\(d) if (cond) filter(d, am == 1) else d)() |>
summarise(m = mean(wt))
Upvotes: 18