apply condition if val for continuous minutes
I have this data:
library(tidyverse)
library(lubridate)
dates <- c("01/01/18 1:00:00 PM" ,"01/01/18 1:01:00 PM",
"01/01/18 1:02:00 PM" ,"01/01/18 1:03:00 PM",
"01/01/18 1:04:00 PM" ,"01/01/18 1:05:00 PM",
"01/01/18 1:06:00 PM" ,"01/01/18 1:07:00 PM",
"01/01/18 1:08:00 PM" ,"01/01/18 1:09:00 PM",
"01/01/18 1:10:00 PM" ,"01/01/18 1:11:00 PM")
vals <- c(1, 2, 3, 3, 15, 16, 17, 18, 1, 2, 1, 22)
datfr <- data.frame(dates, vals)
datfr$dates <- dmy_hms(datfr$dates)
I want to apply a condition:
if the val is < 4 for 2 continuous minutes period then true
I tried :
datfr$gr <- datfr %>%
group_by(by2min = cut(dates, "2 min")) %>%
summarise(cond = (vals < 4))
but it gives me:
column cond must be length 1 not 2
and I am not sure for the approach.
So, my expected output:
dates vals cond
1 2018-01-01 13:00:00 1
2 2018-01-01 13:01:00 2
3 2018-01-01 13:02:00 3 TRUE
4 2018-01-01 13:03:00 3
5 2018-01-01 13:04:00 15 FALSE
6 2018-01-01 13:05:00 16
7 2018-01-01 13:06:00 17 FALSE
8 2018-01-01 13:07:00 18
9 2018-01-01 13:08:00 1 FALSE
10 2018-01-01 13:09:00 2
11 2018-01-01 13:10:00 1 TRUE
12 2018-01-01 13:11:00 22
Hence, if the for 2 continuous minutes the val is < 4 then true.
r dplyr lubridate
add a comment |
I have this data:
library(tidyverse)
library(lubridate)
dates <- c("01/01/18 1:00:00 PM" ,"01/01/18 1:01:00 PM",
"01/01/18 1:02:00 PM" ,"01/01/18 1:03:00 PM",
"01/01/18 1:04:00 PM" ,"01/01/18 1:05:00 PM",
"01/01/18 1:06:00 PM" ,"01/01/18 1:07:00 PM",
"01/01/18 1:08:00 PM" ,"01/01/18 1:09:00 PM",
"01/01/18 1:10:00 PM" ,"01/01/18 1:11:00 PM")
vals <- c(1, 2, 3, 3, 15, 16, 17, 18, 1, 2, 1, 22)
datfr <- data.frame(dates, vals)
datfr$dates <- dmy_hms(datfr$dates)
I want to apply a condition:
if the val is < 4 for 2 continuous minutes period then true
I tried :
datfr$gr <- datfr %>%
group_by(by2min = cut(dates, "2 min")) %>%
summarise(cond = (vals < 4))
but it gives me:
column cond must be length 1 not 2
and I am not sure for the approach.
So, my expected output:
dates vals cond
1 2018-01-01 13:00:00 1
2 2018-01-01 13:01:00 2
3 2018-01-01 13:02:00 3 TRUE
4 2018-01-01 13:03:00 3
5 2018-01-01 13:04:00 15 FALSE
6 2018-01-01 13:05:00 16
7 2018-01-01 13:06:00 17 FALSE
8 2018-01-01 13:07:00 18
9 2018-01-01 13:08:00 1 FALSE
10 2018-01-01 13:09:00 2
11 2018-01-01 13:10:00 1 TRUE
12 2018-01-01 13:11:00 22
Hence, if the for 2 continuous minutes the val is < 4 then true.
r dplyr lubridate
I'd start fromsummarise(cond = all(vals < 4))
adjusting the code according to the desired output. plus, yourcut
do not cut data into 2min intervals, at least not the way you show in your desired output.
– utubun
Nov 27 '18 at 10:16
add a comment |
I have this data:
library(tidyverse)
library(lubridate)
dates <- c("01/01/18 1:00:00 PM" ,"01/01/18 1:01:00 PM",
"01/01/18 1:02:00 PM" ,"01/01/18 1:03:00 PM",
"01/01/18 1:04:00 PM" ,"01/01/18 1:05:00 PM",
"01/01/18 1:06:00 PM" ,"01/01/18 1:07:00 PM",
"01/01/18 1:08:00 PM" ,"01/01/18 1:09:00 PM",
"01/01/18 1:10:00 PM" ,"01/01/18 1:11:00 PM")
vals <- c(1, 2, 3, 3, 15, 16, 17, 18, 1, 2, 1, 22)
datfr <- data.frame(dates, vals)
datfr$dates <- dmy_hms(datfr$dates)
I want to apply a condition:
if the val is < 4 for 2 continuous minutes period then true
I tried :
datfr$gr <- datfr %>%
group_by(by2min = cut(dates, "2 min")) %>%
summarise(cond = (vals < 4))
but it gives me:
column cond must be length 1 not 2
and I am not sure for the approach.
So, my expected output:
dates vals cond
1 2018-01-01 13:00:00 1
2 2018-01-01 13:01:00 2
3 2018-01-01 13:02:00 3 TRUE
4 2018-01-01 13:03:00 3
5 2018-01-01 13:04:00 15 FALSE
6 2018-01-01 13:05:00 16
7 2018-01-01 13:06:00 17 FALSE
8 2018-01-01 13:07:00 18
9 2018-01-01 13:08:00 1 FALSE
10 2018-01-01 13:09:00 2
11 2018-01-01 13:10:00 1 TRUE
12 2018-01-01 13:11:00 22
Hence, if the for 2 continuous minutes the val is < 4 then true.
r dplyr lubridate
I have this data:
library(tidyverse)
library(lubridate)
dates <- c("01/01/18 1:00:00 PM" ,"01/01/18 1:01:00 PM",
"01/01/18 1:02:00 PM" ,"01/01/18 1:03:00 PM",
"01/01/18 1:04:00 PM" ,"01/01/18 1:05:00 PM",
"01/01/18 1:06:00 PM" ,"01/01/18 1:07:00 PM",
"01/01/18 1:08:00 PM" ,"01/01/18 1:09:00 PM",
"01/01/18 1:10:00 PM" ,"01/01/18 1:11:00 PM")
vals <- c(1, 2, 3, 3, 15, 16, 17, 18, 1, 2, 1, 22)
datfr <- data.frame(dates, vals)
datfr$dates <- dmy_hms(datfr$dates)
I want to apply a condition:
if the val is < 4 for 2 continuous minutes period then true
I tried :
datfr$gr <- datfr %>%
group_by(by2min = cut(dates, "2 min")) %>%
summarise(cond = (vals < 4))
but it gives me:
column cond must be length 1 not 2
and I am not sure for the approach.
So, my expected output:
dates vals cond
1 2018-01-01 13:00:00 1
2 2018-01-01 13:01:00 2
3 2018-01-01 13:02:00 3 TRUE
4 2018-01-01 13:03:00 3
5 2018-01-01 13:04:00 15 FALSE
6 2018-01-01 13:05:00 16
7 2018-01-01 13:06:00 17 FALSE
8 2018-01-01 13:07:00 18
9 2018-01-01 13:08:00 1 FALSE
10 2018-01-01 13:09:00 2
11 2018-01-01 13:10:00 1 TRUE
12 2018-01-01 13:11:00 22
Hence, if the for 2 continuous minutes the val is < 4 then true.
r dplyr lubridate
r dplyr lubridate
edited Nov 27 '18 at 9:29
George
asked Nov 27 '18 at 9:15
GeorgeGeorge
2,793851114
2,793851114
I'd start fromsummarise(cond = all(vals < 4))
adjusting the code according to the desired output. plus, yourcut
do not cut data into 2min intervals, at least not the way you show in your desired output.
– utubun
Nov 27 '18 at 10:16
add a comment |
I'd start fromsummarise(cond = all(vals < 4))
adjusting the code according to the desired output. plus, yourcut
do not cut data into 2min intervals, at least not the way you show in your desired output.
– utubun
Nov 27 '18 at 10:16
I'd start from
summarise(cond = all(vals < 4))
adjusting the code according to the desired output. plus, your cut
do not cut data into 2min intervals, at least not the way you show in your desired output.– utubun
Nov 27 '18 at 10:16
I'd start from
summarise(cond = all(vals < 4))
adjusting the code according to the desired output. plus, your cut
do not cut data into 2min intervals, at least not the way you show in your desired output.– utubun
Nov 27 '18 at 10:16
add a comment |
3 Answers
3
active
oldest
votes
Let's assume your data is in a format where the time diffs are 1 minute between row entries
datfr$cond<-
zoo::rollapply(data = datfr$vals, width = 3, FUN = function(x) { if (all(x < 4)) return(TRUE) else return(FALSE) }, align = "right", fill = FALSE)
result:
# dates vals cond
#1 2018-01-01 13:00:00 1 FALSE
#2 2018-01-01 13:01:00 2 FALSE
#3 2018-01-01 13:02:00 3 TRUE
#4 2018-01-01 13:03:00 3 TRUE
#5 2018-01-01 13:04:00 15 FALSE
#6 2018-01-01 13:05:00 16 FALSE
#7 2018-01-01 13:06:00 17 FALSE
#8 2018-01-01 13:07:00 18 FALSE
#9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 FALSE
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
So, if I want to apply the condition by every 120 minutes, I would userollaply(datfr$vals, width = 120)
orwidth = 121
?
– George
Nov 27 '18 at 11:40
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
|
show 1 more comment
I've tried just to reproduce your desired output as close as it possible. I assume that empty elements of cond
are NA
s. In case if cond
is a character
variable, and empty elements represent s
it's easy to adjust the output by adding additional mutate(cond = coalesce(as.character(cond), ""))
. I failed with conversion of the last value into s/NA
.
#library(tidyverse)
datfr %>%
arrange(dates) %>%
group_by(by2min = lag(cut(c(min(dates), dates), "2 min"))[-1]) %>%
mutate(dates = max(dates)) %>%
group_by(dates) %>%
summarise(cond = all(vals < 4), vals = last(vals)) %>%
right_join(datfr, by = c('dates', 'vals')) %>%
select(dates, vals, cond)
# # A tibble: 12 x 3
# dates vals cond
# <dttm> <dbl> <lgl>
# 1 2018-01-01 13:00:00 1 NA
# 2 2018-01-01 13:01:00 2 NA
# 3 2018-01-01 13:02:00 3 TRUE
# 4 2018-01-01 13:03:00 3 NA
# 5 2018-01-01 13:04:00 15 FALSE
# 6 2018-01-01 13:05:00 16 NA
# 7 2018-01-01 13:06:00 17 FALSE
# 8 2018-01-01 13:07:00 18 NA
# 9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 NA
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
1
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
add a comment |
How about using rollapply
?
zoo::rollapply(datfr$vals, 3, by = 1, function(x) sum(x<4) == 2)
Edit: simplified function
1
your function can be simplified to:function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53496225%2fapply-condition-if-val-for-continuous-minutes%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Let's assume your data is in a format where the time diffs are 1 minute between row entries
datfr$cond<-
zoo::rollapply(data = datfr$vals, width = 3, FUN = function(x) { if (all(x < 4)) return(TRUE) else return(FALSE) }, align = "right", fill = FALSE)
result:
# dates vals cond
#1 2018-01-01 13:00:00 1 FALSE
#2 2018-01-01 13:01:00 2 FALSE
#3 2018-01-01 13:02:00 3 TRUE
#4 2018-01-01 13:03:00 3 TRUE
#5 2018-01-01 13:04:00 15 FALSE
#6 2018-01-01 13:05:00 16 FALSE
#7 2018-01-01 13:06:00 17 FALSE
#8 2018-01-01 13:07:00 18 FALSE
#9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 FALSE
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
So, if I want to apply the condition by every 120 minutes, I would userollaply(datfr$vals, width = 120)
orwidth = 121
?
– George
Nov 27 '18 at 11:40
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
|
show 1 more comment
Let's assume your data is in a format where the time diffs are 1 minute between row entries
datfr$cond<-
zoo::rollapply(data = datfr$vals, width = 3, FUN = function(x) { if (all(x < 4)) return(TRUE) else return(FALSE) }, align = "right", fill = FALSE)
result:
# dates vals cond
#1 2018-01-01 13:00:00 1 FALSE
#2 2018-01-01 13:01:00 2 FALSE
#3 2018-01-01 13:02:00 3 TRUE
#4 2018-01-01 13:03:00 3 TRUE
#5 2018-01-01 13:04:00 15 FALSE
#6 2018-01-01 13:05:00 16 FALSE
#7 2018-01-01 13:06:00 17 FALSE
#8 2018-01-01 13:07:00 18 FALSE
#9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 FALSE
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
So, if I want to apply the condition by every 120 minutes, I would userollaply(datfr$vals, width = 120)
orwidth = 121
?
– George
Nov 27 '18 at 11:40
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
|
show 1 more comment
Let's assume your data is in a format where the time diffs are 1 minute between row entries
datfr$cond<-
zoo::rollapply(data = datfr$vals, width = 3, FUN = function(x) { if (all(x < 4)) return(TRUE) else return(FALSE) }, align = "right", fill = FALSE)
result:
# dates vals cond
#1 2018-01-01 13:00:00 1 FALSE
#2 2018-01-01 13:01:00 2 FALSE
#3 2018-01-01 13:02:00 3 TRUE
#4 2018-01-01 13:03:00 3 TRUE
#5 2018-01-01 13:04:00 15 FALSE
#6 2018-01-01 13:05:00 16 FALSE
#7 2018-01-01 13:06:00 17 FALSE
#8 2018-01-01 13:07:00 18 FALSE
#9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 FALSE
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
Let's assume your data is in a format where the time diffs are 1 minute between row entries
datfr$cond<-
zoo::rollapply(data = datfr$vals, width = 3, FUN = function(x) { if (all(x < 4)) return(TRUE) else return(FALSE) }, align = "right", fill = FALSE)
result:
# dates vals cond
#1 2018-01-01 13:00:00 1 FALSE
#2 2018-01-01 13:01:00 2 FALSE
#3 2018-01-01 13:02:00 3 TRUE
#4 2018-01-01 13:03:00 3 TRUE
#5 2018-01-01 13:04:00 15 FALSE
#6 2018-01-01 13:05:00 16 FALSE
#7 2018-01-01 13:06:00 17 FALSE
#8 2018-01-01 13:07:00 18 FALSE
#9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 FALSE
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
answered Nov 27 '18 at 9:52
Andre ElricoAndre Elrico
5,73311229
5,73311229
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
So, if I want to apply the condition by every 120 minutes, I would userollaply(datfr$vals, width = 120)
orwidth = 121
?
– George
Nov 27 '18 at 11:40
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
|
show 1 more comment
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
So, if I want to apply the condition by every 120 minutes, I would userollaply(datfr$vals, width = 120)
orwidth = 121
?
– George
Nov 27 '18 at 11:40
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
Thanks! (upv..)
– George
Nov 27 '18 at 11:26
So, if I want to apply the condition by every 120 minutes, I would use
rollaply(datfr$vals, width = 120)
or width = 121
?– George
Nov 27 '18 at 11:40
So, if I want to apply the condition by every 120 minutes, I would use
rollaply(datfr$vals, width = 120)
or width = 121
?– George
Nov 27 '18 at 11:40
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
not entirely sure what you want. Make an easy example for yourself with maybe window of 10 and see what you need. 10 or 11. This logic will transfer to 120.
– Andre Elrico
Nov 27 '18 at 11:45
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
I mean, if I had many rows of data and wanted to apply the condition for every 120 continuous minutes instead of 2 minutes.
– George
Nov 27 '18 at 11:53
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
for 2 minutes I needed to use 3 so I would assume for 120 i need a width of 121
– Andre Elrico
Nov 27 '18 at 12:16
|
show 1 more comment
I've tried just to reproduce your desired output as close as it possible. I assume that empty elements of cond
are NA
s. In case if cond
is a character
variable, and empty elements represent s
it's easy to adjust the output by adding additional mutate(cond = coalesce(as.character(cond), ""))
. I failed with conversion of the last value into s/NA
.
#library(tidyverse)
datfr %>%
arrange(dates) %>%
group_by(by2min = lag(cut(c(min(dates), dates), "2 min"))[-1]) %>%
mutate(dates = max(dates)) %>%
group_by(dates) %>%
summarise(cond = all(vals < 4), vals = last(vals)) %>%
right_join(datfr, by = c('dates', 'vals')) %>%
select(dates, vals, cond)
# # A tibble: 12 x 3
# dates vals cond
# <dttm> <dbl> <lgl>
# 1 2018-01-01 13:00:00 1 NA
# 2 2018-01-01 13:01:00 2 NA
# 3 2018-01-01 13:02:00 3 TRUE
# 4 2018-01-01 13:03:00 3 NA
# 5 2018-01-01 13:04:00 15 FALSE
# 6 2018-01-01 13:05:00 16 NA
# 7 2018-01-01 13:06:00 17 FALSE
# 8 2018-01-01 13:07:00 18 NA
# 9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 NA
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
1
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
add a comment |
I've tried just to reproduce your desired output as close as it possible. I assume that empty elements of cond
are NA
s. In case if cond
is a character
variable, and empty elements represent s
it's easy to adjust the output by adding additional mutate(cond = coalesce(as.character(cond), ""))
. I failed with conversion of the last value into s/NA
.
#library(tidyverse)
datfr %>%
arrange(dates) %>%
group_by(by2min = lag(cut(c(min(dates), dates), "2 min"))[-1]) %>%
mutate(dates = max(dates)) %>%
group_by(dates) %>%
summarise(cond = all(vals < 4), vals = last(vals)) %>%
right_join(datfr, by = c('dates', 'vals')) %>%
select(dates, vals, cond)
# # A tibble: 12 x 3
# dates vals cond
# <dttm> <dbl> <lgl>
# 1 2018-01-01 13:00:00 1 NA
# 2 2018-01-01 13:01:00 2 NA
# 3 2018-01-01 13:02:00 3 TRUE
# 4 2018-01-01 13:03:00 3 NA
# 5 2018-01-01 13:04:00 15 FALSE
# 6 2018-01-01 13:05:00 16 NA
# 7 2018-01-01 13:06:00 17 FALSE
# 8 2018-01-01 13:07:00 18 NA
# 9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 NA
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
1
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
add a comment |
I've tried just to reproduce your desired output as close as it possible. I assume that empty elements of cond
are NA
s. In case if cond
is a character
variable, and empty elements represent s
it's easy to adjust the output by adding additional mutate(cond = coalesce(as.character(cond), ""))
. I failed with conversion of the last value into s/NA
.
#library(tidyverse)
datfr %>%
arrange(dates) %>%
group_by(by2min = lag(cut(c(min(dates), dates), "2 min"))[-1]) %>%
mutate(dates = max(dates)) %>%
group_by(dates) %>%
summarise(cond = all(vals < 4), vals = last(vals)) %>%
right_join(datfr, by = c('dates', 'vals')) %>%
select(dates, vals, cond)
# # A tibble: 12 x 3
# dates vals cond
# <dttm> <dbl> <lgl>
# 1 2018-01-01 13:00:00 1 NA
# 2 2018-01-01 13:01:00 2 NA
# 3 2018-01-01 13:02:00 3 TRUE
# 4 2018-01-01 13:03:00 3 NA
# 5 2018-01-01 13:04:00 15 FALSE
# 6 2018-01-01 13:05:00 16 NA
# 7 2018-01-01 13:06:00 17 FALSE
# 8 2018-01-01 13:07:00 18 NA
# 9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 NA
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
I've tried just to reproduce your desired output as close as it possible. I assume that empty elements of cond
are NA
s. In case if cond
is a character
variable, and empty elements represent s
it's easy to adjust the output by adding additional mutate(cond = coalesce(as.character(cond), ""))
. I failed with conversion of the last value into s/NA
.
#library(tidyverse)
datfr %>%
arrange(dates) %>%
group_by(by2min = lag(cut(c(min(dates), dates), "2 min"))[-1]) %>%
mutate(dates = max(dates)) %>%
group_by(dates) %>%
summarise(cond = all(vals < 4), vals = last(vals)) %>%
right_join(datfr, by = c('dates', 'vals')) %>%
select(dates, vals, cond)
# # A tibble: 12 x 3
# dates vals cond
# <dttm> <dbl> <lgl>
# 1 2018-01-01 13:00:00 1 NA
# 2 2018-01-01 13:01:00 2 NA
# 3 2018-01-01 13:02:00 3 TRUE
# 4 2018-01-01 13:03:00 3 NA
# 5 2018-01-01 13:04:00 15 FALSE
# 6 2018-01-01 13:05:00 16 NA
# 7 2018-01-01 13:06:00 17 FALSE
# 8 2018-01-01 13:07:00 18 NA
# 9 2018-01-01 13:08:00 1 FALSE
#10 2018-01-01 13:09:00 2 NA
#11 2018-01-01 13:10:00 1 TRUE
#12 2018-01-01 13:11:00 22 FALSE
answered Nov 27 '18 at 10:58
utubunutubun
1,6281912
1,6281912
1
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
add a comment |
1
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
1
1
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
Thanks!Nice solution.I prefer the rollapply though.(upv)
– George
Nov 27 '18 at 11:28
add a comment |
How about using rollapply
?
zoo::rollapply(datfr$vals, 3, by = 1, function(x) sum(x<4) == 2)
Edit: simplified function
1
your function can be simplified to:function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
add a comment |
How about using rollapply
?
zoo::rollapply(datfr$vals, 3, by = 1, function(x) sum(x<4) == 2)
Edit: simplified function
1
your function can be simplified to:function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
add a comment |
How about using rollapply
?
zoo::rollapply(datfr$vals, 3, by = 1, function(x) sum(x<4) == 2)
Edit: simplified function
How about using rollapply
?
zoo::rollapply(datfr$vals, 3, by = 1, function(x) sum(x<4) == 2)
Edit: simplified function
edited Nov 27 '18 at 9:58
answered Nov 27 '18 at 9:44
CIAndrewsCIAndrews
28817
28817
1
your function can be simplified to:function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
add a comment |
1
your function can be simplified to:function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
1
1
your function can be simplified to:
function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
your function can be simplified to:
function(x) length(x[x<4]) == 2)
or evenfunction(x) sum(x<4) == 2
– sindri_baldur
Nov 27 '18 at 9:54
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
Thanks, the problem is that it returns 10 rows and the data has 12, so I am receiving an error.
– George
Nov 27 '18 at 11:27
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53496225%2fapply-condition-if-val-for-continuous-minutes%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I'd start from
summarise(cond = all(vals < 4))
adjusting the code according to the desired output. plus, yourcut
do not cut data into 2min intervals, at least not the way you show in your desired output.– utubun
Nov 27 '18 at 10:16