Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flag a progressive decrease in values in list

Tags:

list

r

I have a dataframe with columns containing lists of values:

dt
   onset_l  coda_l
1     3, 7 7, 4, 1
3        7 7, 1, 3
12    1, 7 7, 4, 1
21    6, 7 7, 4, 1
23       7 7, 1, 5

What I want to do is create a new column, say, coda_flag, that flags whether the values in column coda_l progressively decrease or not.

I've tried this lapply method:

dt$coda_flag <- lapply(dt$coda_l, function(x) ifelse(x[1] > x[2] & x[2] > x[3], 1, 0))

The output is okay but I dislike that I have to enumerate x[1], x[2] and so on because in some cases I may not know the exact number of values in the lists.

The desired output would be:

dt
   onset_l  coda_l coda_flag
1     3, 7 7, 4, 1         1  # values do progressively decrease
3        7 7, 1, 3         0  # values do not progressively decrease
12    1, 7 7, 4, 1         1
21    6, 7 7, 4, 1         1
23       7 7, 1, 5         0

How can this be achieved?

Reproducible data:

dt <- structure(list(onset_l = list(c("3", "7"), "7", c("1", "7"), 
    c("6", "7"), "7"), coda_l = list(c("7", "4", "1"), c("7", 
"1", "3"), c("7", "4", "1"), c("7", "4", "1"), c("7", "1", "5"
))), row.names = c(1L, 3L, 12L, 21L, 23L), class = "data.frame")
like image 587
Chris Ruehlemann Avatar asked Jun 15 '26 06:06

Chris Ruehlemann


2 Answers

You can use is.unsorted() - although it can only detect increasing order so it's necessary to reverse the vector first.

dt$coda_flag <- +!sapply(dt$coda_l, function(x) is.unsorted(rev(as.numeric(x))))

   onset_l  coda_l coda_flag
1     3, 7 7, 4, 1         1
3        7 7, 1, 3         0
12    1, 7 7, 4, 1         1
21    6, 7 7, 4, 1         1
23       7 7, 1, 5         0

Note the strictly argument controls what happens in the event of tied values.

x <- c(1, 2, 2, 3)

is.unsorted(x)
[1] FALSE

is.unsorted(x, strictly = TRUE)
[1] TRUE
like image 71
Ritchie Sacramento Avatar answered Jun 17 '26 20:06

Ritchie Sacramento


One dplyr and purrr solution could be:

dt %>%
 mutate(coda_flag = map_int(.x = coda_l, ~ +(all(diff(as.numeric(.x)) < 1))))

  onset_l  coda_l coda_flag
1    3, 7 7, 4, 1         1
2       7 7, 1, 3         0
3    1, 7 7, 4, 1         1
4    6, 7 7, 4, 1         1
5       7 7, 1, 5         0
like image 28
tmfmnk Avatar answered Jun 17 '26 22:06

tmfmnk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!