Reputation: 157
I would like to calculate one single variable depending on a column specification.
example.df <-
data.frame(trial.number = rep(1:10,
each = 10), GY = sample(-200:200,
100, replace = T), target.position
= rep(c("up","down","up","down",
"up"), each = 20))
test <- example.df %>%
group_by(trial.number) %>%
summarise(pxpos =
max(GY[target.position == "up"]) |
min(GY[target.position == "down"]))
So, if the target.position is "up", I want to know the max GY in that trial, when target.position = "down", I want the variable to take the min(GY).
This however doesn't work. I do believe that it is possible though! Thanks for help
Upvotes: 1
Views: 55
Reputation: 887851
We can use case_when
example.df %>%
group_by(trial.number) %>%
summarise(pxpos = case_when(first(target.position) == "up" ~ max(GY),
TRUE ~ min(GY)))
# A tibble: 10 x 2
# trial.number pxpos
# <int> <dbl>
#1 1 177
#2 2 183
#3 3 -142
#4 4 -191
#5 5 143
#6 6 158
#7 7 -162
#8 8 -200
#9 9 194
#10 10 113
Upvotes: 1
Reputation: 389235
Assuming you'll always have the same value in target.position
in each trial.numer
we can group_by
trial.number
and calculate max(GY)
if the first value is "up" or else calculate min
.
library(dplyr)
example.df %>%
group_by(trial.number) %>%
summarise(pxpos = if_else(target.position[1] == "up", max(GY), min(GY)))
# trial.number pxpos
# <int> <dbl>
# 1 1 177
# 2 2 183
# 3 3 -142
# 4 4 -191
# 5 5 143
# 6 6 158
# 7 7 -162
# 8 8 -200
# 9 9 194
#10 10 113
As pointed out by @Axeman, if_else
is slow, we can instead replace it with simple if
else
example.df %>%
group_by(trial.number) %>%
summarise(pxpos = if (target.position[1] == "up") max(GY) else min(GY))
data
set.seed(123)
example.df <- data.frame(trial.number = rep(1:10, each = 10),
GY = sample(-200:200,100, replace = T),
target.position = rep(c("up","down","up","down",
"up"), each = 20))
Upvotes: 3
Reputation: 40171
Another dplyr
solution, using data provided by @Ronak Shah:
example.df %>%
group_by(trial.number) %>%
mutate(res = ifelse(target.position == "up", max(GY),
ifelse(target.position == "down", min(GY), NA))) %>%
summarise(res = first(res))
trial.number res
<int> <dbl>
1 1 177.
2 2 183.
3 3 -142.
4 4 -191.
5 5 143.
6 6 158.
7 7 -162.
8 8 -200.
9 9 194.
10 10 113.
Upvotes: 1