I want to calculate the number of times elements in my data frame go from <=0 to >0 for each factor/level.
A simple code to calculate the number of times the values switch sign is not sufficient, because I am interested in including values of 0. I also only want the number of times values go from <=0 to >0, and not include the number of times it goes from >0 to <=0. Anyone know a good way to approach this?
My data is set up as follows:
factor<-c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)
value<-c(2,-1,0,-1,3,-1,0,-1,2,-1,4,5,-1,-1,2,2,-3,-2)
df <- cbind(factor,value)
I want a table with the factors and the number of cycles (times it goes from <=0 to >0) like this.
factor cycles
[1,] 1 1
[2,] 2 2
[3,] 3 1
Here's a simple approach in base R:
df <- data.frame(factor,value)
df$signish = value <= 0
foo = function(x) sum(x[-length(x)] > x[-1])
# use tapply or aggregate to apply the function by group
tapply(df$signish, df$factor, FUN = foo)
# 1 2 3
# 1 2 1
aggregate(signish ~ factor, data = df, foo)
# factor signish
# 1 1 1
# 2 2 2
# 3 3 1
Of course, you could use dplyr
or data.table
to easily do the grouped operation if you prefer.
One possibility involving dplyr
could be:
df %>%
group_by(factor) %>%
mutate(value = sign(value)) %>%
summarise(value = sum(value == 1 & lag(value, default = first(value)) <= 0))
Or:
df %>%
group_by(factor) %>%
summarise(value = sum(diff(sign(value)) == 2))
The continuation of that idea with base R
:
aggregate(value ~ factor,
FUN = function(x) sum(diff(sign(x)) == 2),
data = df)
factor value
<dbl> <int>
1 1 1
2 2 2
3 3 1
Sample data:
df <- data.frame(factor, value,
stringsAsFactors = FALSE)
Another option using base
:
aggregate(val ~ fct, dat, function(x) sum(diff(x <= 0) < 0))
# fct val
# 1 1 1
# 2 2 2
# 3 3 1
dat <- data.frame(
fct = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3),
val = c(2, -1, 0, -1, 3, -1, 0, -1, 2, -1, 4, 5, -1, -1, 2, 2, -3, -2)
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With