How to keep dropping the first value, until the sum of the vector is less than 20?
I am looking for a function which takes a vector and keeps dropping the first value until the sum of the vector is less than 20. Return the remaining values.
I've tried both a for-loop and while-loop and can't find a solution.
vec <- c(3,5,3,4,3,9,1,8,2,5)
short <- function(vec){
for (i in 1:length(vec)){
while (!is.na((sum(vec)) < 20)){
vec <- vec[i+1:length(vec)]
#vec.remove(i)
}
}
The expected output should be:
1,8,2,5
which is less than 20.
r loops for-loop vector while-loop
New contributor
add a comment |
I am looking for a function which takes a vector and keeps dropping the first value until the sum of the vector is less than 20. Return the remaining values.
I've tried both a for-loop and while-loop and can't find a solution.
vec <- c(3,5,3,4,3,9,1,8,2,5)
short <- function(vec){
for (i in 1:length(vec)){
while (!is.na((sum(vec)) < 20)){
vec <- vec[i+1:length(vec)]
#vec.remove(i)
}
}
The expected output should be:
1,8,2,5
which is less than 20.
r loops for-loop vector while-loop
New contributor
add a comment |
I am looking for a function which takes a vector and keeps dropping the first value until the sum of the vector is less than 20. Return the remaining values.
I've tried both a for-loop and while-loop and can't find a solution.
vec <- c(3,5,3,4,3,9,1,8,2,5)
short <- function(vec){
for (i in 1:length(vec)){
while (!is.na((sum(vec)) < 20)){
vec <- vec[i+1:length(vec)]
#vec.remove(i)
}
}
The expected output should be:
1,8,2,5
which is less than 20.
r loops for-loop vector while-loop
New contributor
I am looking for a function which takes a vector and keeps dropping the first value until the sum of the vector is less than 20. Return the remaining values.
I've tried both a for-loop and while-loop and can't find a solution.
vec <- c(3,5,3,4,3,9,1,8,2,5)
short <- function(vec){
for (i in 1:length(vec)){
while (!is.na((sum(vec)) < 20)){
vec <- vec[i+1:length(vec)]
#vec.remove(i)
}
}
The expected output should be:
1,8,2,5
which is less than 20.
r loops for-loop vector while-loop
r loops for-loop vector while-loop
New contributor
New contributor
edited 5 hours ago
Khaynes
443417
443417
New contributor
asked 6 hours ago
Hanna DupHanna Dup
366
366
New contributor
New contributor
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
You need to remove the first value each time, so your while
loop should be,
while (sum(x, na.rm = TRUE) >= 20) {
x <- x[-1]
}
#[1] 1 8 2 5
1
From the OP's post, might look like their actual data has NA's in it? If so, remember to definesum(x, na.rm = TRUE)
– Khaynes
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
3
Can the downvoter explain please? I went withwhile
to point out OP's mistake! Downvote is at the very least biased
– Sotos
5 hours ago
add a comment |
Looking at the expected output it looks like you want to drop values until sum of remaining values is less than 20.
We can create a function
drop_20 <- function(vec) {
tail(vec, sum(cumsum(rev(vec)) < 20))
}
drop_20(vec)
#[1] 1 8 2 5
Trying it on another input
drop_20(1:10)
#[1] 9 10
Breaking down the function, first the vec
vec = c(3,5,3,4,3,9,1,8,2,5)
We then rev
erse it
rev(vec)
#[1] 5 2 8 1 9 3 4 3 5 3
take cumulative sum over it (cumsum
)
cumsum(vec)
#[1] 3 8 11 15 18 27 28 36 38 43
Find out number of enteries that are less than 20
cumsum(rev(vec)) < 20
#[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
sum(cumsum(rev(vec)) < 20)
#[1] 4
and finally subset these last enteries using tail
.
A slight modification in the code and it should be able to handle NA
s as well
drop_20 <- function(vec) {
tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20))
}
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
drop_20(vec)
#[1] 3 4 9 NA 1 2
The logic being we replace
NA
with zeroes and then take the cumsum
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
@HannaDup must be because ofNA
s you may take a look at the updated answer now.
– Ronak Shah
5 hours ago
add a comment |
base solution without loops
not my most readable code ever, but it's pretty fast (see benchmarking below)
rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20] )
#[1] 1 8 2 5
note: 'borrowed' the NA
-handling from @Ronak's answer
sample datavec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
benchmarks
microbenchmark::microbenchmark(
Sotos = {
while (sum(vec, na.rm = TRUE) >= 20) {
vec <- vec[-1]
}
},
Ronak = tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20)),
Wimpel = rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20]),
WimpelMarkus = vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Sotos 2096.795 2127.373 2288.15768 2152.6795 2425.4740 3071.684 100
# Ronak 30.127 33.440 42.54770 37.2055 49.4080 101.827 100
# Wimpel 13.557 15.063 17.65734 16.1175 18.5285 38.261 100
# WimpelMarkus 7.532 8.737 12.60520 10.0925 15.9680 45.491 100
I think you can save a couple ofrev
's here:vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.
– markus
4 hours ago
1
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
add a comment |
I would go with Reduce
vec[Reduce(f = "+", x = vec, accumulate = T, right = T) < 20]
##[1] 1 8 2 5
Alternatively, define Reduce with function sum
with the conditional argument na.rm = T
in order to hanlde NAs if desired:
vec2 <- c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
vec2[Reduce(f = function(a,b) sum(a, b, na.rm = T), x = vec2, accumulate = TRUE, right = T) < 20]
##[1] 3 4 9 NA 1 2
I find the Reduce option to start from right (end of the integer vector), and hence not having to reverse it first, convenient.
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
});
}
});
Hanna Dup is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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%2f54212081%2fhow-to-keep-dropping-the-first-value-until-the-sum-of-the-vector-is-less-than-2%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You need to remove the first value each time, so your while
loop should be,
while (sum(x, na.rm = TRUE) >= 20) {
x <- x[-1]
}
#[1] 1 8 2 5
1
From the OP's post, might look like their actual data has NA's in it? If so, remember to definesum(x, na.rm = TRUE)
– Khaynes
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
3
Can the downvoter explain please? I went withwhile
to point out OP's mistake! Downvote is at the very least biased
– Sotos
5 hours ago
add a comment |
You need to remove the first value each time, so your while
loop should be,
while (sum(x, na.rm = TRUE) >= 20) {
x <- x[-1]
}
#[1] 1 8 2 5
1
From the OP's post, might look like their actual data has NA's in it? If so, remember to definesum(x, na.rm = TRUE)
– Khaynes
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
3
Can the downvoter explain please? I went withwhile
to point out OP's mistake! Downvote is at the very least biased
– Sotos
5 hours ago
add a comment |
You need to remove the first value each time, so your while
loop should be,
while (sum(x, na.rm = TRUE) >= 20) {
x <- x[-1]
}
#[1] 1 8 2 5
You need to remove the first value each time, so your while
loop should be,
while (sum(x, na.rm = TRUE) >= 20) {
x <- x[-1]
}
#[1] 1 8 2 5
edited 5 hours ago
answered 5 hours ago
SotosSotos
28.8k51640
28.8k51640
1
From the OP's post, might look like their actual data has NA's in it? If so, remember to definesum(x, na.rm = TRUE)
– Khaynes
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
3
Can the downvoter explain please? I went withwhile
to point out OP's mistake! Downvote is at the very least biased
– Sotos
5 hours ago
add a comment |
1
From the OP's post, might look like their actual data has NA's in it? If so, remember to definesum(x, na.rm = TRUE)
– Khaynes
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
3
Can the downvoter explain please? I went withwhile
to point out OP's mistake! Downvote is at the very least biased
– Sotos
5 hours ago
1
1
From the OP's post, might look like their actual data has NA's in it? If so, remember to define
sum(x, na.rm = TRUE)
– Khaynes
5 hours ago
From the OP's post, might look like their actual data has NA's in it? If so, remember to define
sum(x, na.rm = TRUE)
– Khaynes
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
Good eye! Thanks
– Sotos
5 hours ago
3
3
Can the downvoter explain please? I went with
while
to point out OP's mistake! Downvote is at the very least biased– Sotos
5 hours ago
Can the downvoter explain please? I went with
while
to point out OP's mistake! Downvote is at the very least biased– Sotos
5 hours ago
add a comment |
Looking at the expected output it looks like you want to drop values until sum of remaining values is less than 20.
We can create a function
drop_20 <- function(vec) {
tail(vec, sum(cumsum(rev(vec)) < 20))
}
drop_20(vec)
#[1] 1 8 2 5
Trying it on another input
drop_20(1:10)
#[1] 9 10
Breaking down the function, first the vec
vec = c(3,5,3,4,3,9,1,8,2,5)
We then rev
erse it
rev(vec)
#[1] 5 2 8 1 9 3 4 3 5 3
take cumulative sum over it (cumsum
)
cumsum(vec)
#[1] 3 8 11 15 18 27 28 36 38 43
Find out number of enteries that are less than 20
cumsum(rev(vec)) < 20
#[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
sum(cumsum(rev(vec)) < 20)
#[1] 4
and finally subset these last enteries using tail
.
A slight modification in the code and it should be able to handle NA
s as well
drop_20 <- function(vec) {
tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20))
}
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
drop_20(vec)
#[1] 3 4 9 NA 1 2
The logic being we replace
NA
with zeroes and then take the cumsum
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
@HannaDup must be because ofNA
s you may take a look at the updated answer now.
– Ronak Shah
5 hours ago
add a comment |
Looking at the expected output it looks like you want to drop values until sum of remaining values is less than 20.
We can create a function
drop_20 <- function(vec) {
tail(vec, sum(cumsum(rev(vec)) < 20))
}
drop_20(vec)
#[1] 1 8 2 5
Trying it on another input
drop_20(1:10)
#[1] 9 10
Breaking down the function, first the vec
vec = c(3,5,3,4,3,9,1,8,2,5)
We then rev
erse it
rev(vec)
#[1] 5 2 8 1 9 3 4 3 5 3
take cumulative sum over it (cumsum
)
cumsum(vec)
#[1] 3 8 11 15 18 27 28 36 38 43
Find out number of enteries that are less than 20
cumsum(rev(vec)) < 20
#[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
sum(cumsum(rev(vec)) < 20)
#[1] 4
and finally subset these last enteries using tail
.
A slight modification in the code and it should be able to handle NA
s as well
drop_20 <- function(vec) {
tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20))
}
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
drop_20(vec)
#[1] 3 4 9 NA 1 2
The logic being we replace
NA
with zeroes and then take the cumsum
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
@HannaDup must be because ofNA
s you may take a look at the updated answer now.
– Ronak Shah
5 hours ago
add a comment |
Looking at the expected output it looks like you want to drop values until sum of remaining values is less than 20.
We can create a function
drop_20 <- function(vec) {
tail(vec, sum(cumsum(rev(vec)) < 20))
}
drop_20(vec)
#[1] 1 8 2 5
Trying it on another input
drop_20(1:10)
#[1] 9 10
Breaking down the function, first the vec
vec = c(3,5,3,4,3,9,1,8,2,5)
We then rev
erse it
rev(vec)
#[1] 5 2 8 1 9 3 4 3 5 3
take cumulative sum over it (cumsum
)
cumsum(vec)
#[1] 3 8 11 15 18 27 28 36 38 43
Find out number of enteries that are less than 20
cumsum(rev(vec)) < 20
#[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
sum(cumsum(rev(vec)) < 20)
#[1] 4
and finally subset these last enteries using tail
.
A slight modification in the code and it should be able to handle NA
s as well
drop_20 <- function(vec) {
tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20))
}
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
drop_20(vec)
#[1] 3 4 9 NA 1 2
The logic being we replace
NA
with zeroes and then take the cumsum
Looking at the expected output it looks like you want to drop values until sum of remaining values is less than 20.
We can create a function
drop_20 <- function(vec) {
tail(vec, sum(cumsum(rev(vec)) < 20))
}
drop_20(vec)
#[1] 1 8 2 5
Trying it on another input
drop_20(1:10)
#[1] 9 10
Breaking down the function, first the vec
vec = c(3,5,3,4,3,9,1,8,2,5)
We then rev
erse it
rev(vec)
#[1] 5 2 8 1 9 3 4 3 5 3
take cumulative sum over it (cumsum
)
cumsum(vec)
#[1] 3 8 11 15 18 27 28 36 38 43
Find out number of enteries that are less than 20
cumsum(rev(vec)) < 20
#[1] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
sum(cumsum(rev(vec)) < 20)
#[1] 4
and finally subset these last enteries using tail
.
A slight modification in the code and it should be able to handle NA
s as well
drop_20 <- function(vec) {
tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20))
}
vec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
drop_20(vec)
#[1] 3 4 9 NA 1 2
The logic being we replace
NA
with zeroes and then take the cumsum
edited 5 hours ago
answered 6 hours ago
Ronak ShahRonak Shah
34.8k103855
34.8k103855
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
@HannaDup must be because ofNA
s you may take a look at the updated answer now.
– Ronak Shah
5 hours ago
add a comment |
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
@HannaDup must be because ofNA
s you may take a look at the updated answer now.
– Ronak Shah
5 hours ago
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
I think this is the fastest solution so far which of course matters only on a larger vector.
– Phann
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
@Phann or one a large number of small vectors :).
– snoram
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
FYI, you should also handle NA's somewhere in there. Good idea btw :)
– Sotos
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
I don't know why but when I tried your code, the output is integer(0)
– Hanna Dup
5 hours ago
@HannaDup must be because of
NA
s you may take a look at the updated answer now.– Ronak Shah
5 hours ago
@HannaDup must be because of
NA
s you may take a look at the updated answer now.– Ronak Shah
5 hours ago
add a comment |
base solution without loops
not my most readable code ever, but it's pretty fast (see benchmarking below)
rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20] )
#[1] 1 8 2 5
note: 'borrowed' the NA
-handling from @Ronak's answer
sample datavec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
benchmarks
microbenchmark::microbenchmark(
Sotos = {
while (sum(vec, na.rm = TRUE) >= 20) {
vec <- vec[-1]
}
},
Ronak = tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20)),
Wimpel = rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20]),
WimpelMarkus = vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Sotos 2096.795 2127.373 2288.15768 2152.6795 2425.4740 3071.684 100
# Ronak 30.127 33.440 42.54770 37.2055 49.4080 101.827 100
# Wimpel 13.557 15.063 17.65734 16.1175 18.5285 38.261 100
# WimpelMarkus 7.532 8.737 12.60520 10.0925 15.9680 45.491 100
I think you can save a couple ofrev
's here:vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.
– markus
4 hours ago
1
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
add a comment |
base solution without loops
not my most readable code ever, but it's pretty fast (see benchmarking below)
rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20] )
#[1] 1 8 2 5
note: 'borrowed' the NA
-handling from @Ronak's answer
sample datavec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
benchmarks
microbenchmark::microbenchmark(
Sotos = {
while (sum(vec, na.rm = TRUE) >= 20) {
vec <- vec[-1]
}
},
Ronak = tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20)),
Wimpel = rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20]),
WimpelMarkus = vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Sotos 2096.795 2127.373 2288.15768 2152.6795 2425.4740 3071.684 100
# Ronak 30.127 33.440 42.54770 37.2055 49.4080 101.827 100
# Wimpel 13.557 15.063 17.65734 16.1175 18.5285 38.261 100
# WimpelMarkus 7.532 8.737 12.60520 10.0925 15.9680 45.491 100
I think you can save a couple ofrev
's here:vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.
– markus
4 hours ago
1
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
add a comment |
base solution without loops
not my most readable code ever, but it's pretty fast (see benchmarking below)
rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20] )
#[1] 1 8 2 5
note: 'borrowed' the NA
-handling from @Ronak's answer
sample datavec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
benchmarks
microbenchmark::microbenchmark(
Sotos = {
while (sum(vec, na.rm = TRUE) >= 20) {
vec <- vec[-1]
}
},
Ronak = tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20)),
Wimpel = rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20]),
WimpelMarkus = vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Sotos 2096.795 2127.373 2288.15768 2152.6795 2425.4740 3071.684 100
# Ronak 30.127 33.440 42.54770 37.2055 49.4080 101.827 100
# Wimpel 13.557 15.063 17.65734 16.1175 18.5285 38.261 100
# WimpelMarkus 7.532 8.737 12.60520 10.0925 15.9680 45.491 100
base solution without loops
not my most readable code ever, but it's pretty fast (see benchmarking below)
rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20] )
#[1] 1 8 2 5
note: 'borrowed' the NA
-handling from @Ronak's answer
sample datavec = c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
benchmarks
microbenchmark::microbenchmark(
Sotos = {
while (sum(vec, na.rm = TRUE) >= 20) {
vec <- vec[-1]
}
},
Ronak = tail(vec, sum(cumsum(replace(rev(vec), is.na(rev(vec)), 0)) < 20)),
Wimpel = rev( rev(vec)[cumsum( replace( rev(vec), is.na( rev(vec) ), 0 ) ) < 20]),
WimpelMarkus = vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Sotos 2096.795 2127.373 2288.15768 2152.6795 2425.4740 3071.684 100
# Ronak 30.127 33.440 42.54770 37.2055 49.4080 101.827 100
# Wimpel 13.557 15.063 17.65734 16.1175 18.5285 38.261 100
# WimpelMarkus 7.532 8.737 12.60520 10.0925 15.9680 45.491 100
edited 4 hours ago
answered 5 hours ago
WimpelWimpel
4,585321
4,585321
I think you can save a couple ofrev
's here:vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.
– markus
4 hours ago
1
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
add a comment |
I think you can save a couple ofrev
's here:vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.
– markus
4 hours ago
1
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
I think you can save a couple of
rev
's here: vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.– markus
4 hours ago
I think you can save a couple of
rev
's here: vec[rev(cumsum(rev(replace(vec, is.na(vec), 0))) < 20)]
. This might give a further speed-up.– markus
4 hours ago
1
1
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
@markus you are very very right.. I was a bit too lazy in the copy-pasting I guess... you just reduced execution time with 30-40%! (see updated benchmarks in answer)
– Wimpel
4 hours ago
add a comment |
I would go with Reduce
vec[Reduce(f = "+", x = vec, accumulate = T, right = T) < 20]
##[1] 1 8 2 5
Alternatively, define Reduce with function sum
with the conditional argument na.rm = T
in order to hanlde NAs if desired:
vec2 <- c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
vec2[Reduce(f = function(a,b) sum(a, b, na.rm = T), x = vec2, accumulate = TRUE, right = T) < 20]
##[1] 3 4 9 NA 1 2
I find the Reduce option to start from right (end of the integer vector), and hence not having to reverse it first, convenient.
add a comment |
I would go with Reduce
vec[Reduce(f = "+", x = vec, accumulate = T, right = T) < 20]
##[1] 1 8 2 5
Alternatively, define Reduce with function sum
with the conditional argument na.rm = T
in order to hanlde NAs if desired:
vec2 <- c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
vec2[Reduce(f = function(a,b) sum(a, b, na.rm = T), x = vec2, accumulate = TRUE, right = T) < 20]
##[1] 3 4 9 NA 1 2
I find the Reduce option to start from right (end of the integer vector), and hence not having to reverse it first, convenient.
add a comment |
I would go with Reduce
vec[Reduce(f = "+", x = vec, accumulate = T, right = T) < 20]
##[1] 1 8 2 5
Alternatively, define Reduce with function sum
with the conditional argument na.rm = T
in order to hanlde NAs if desired:
vec2 <- c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
vec2[Reduce(f = function(a,b) sum(a, b, na.rm = T), x = vec2, accumulate = TRUE, right = T) < 20]
##[1] 3 4 9 NA 1 2
I find the Reduce option to start from right (end of the integer vector), and hence not having to reverse it first, convenient.
I would go with Reduce
vec[Reduce(f = "+", x = vec, accumulate = T, right = T) < 20]
##[1] 1 8 2 5
Alternatively, define Reduce with function sum
with the conditional argument na.rm = T
in order to hanlde NAs if desired:
vec2 <- c(3, 2, NA, 4, 5, 1, 2, 3, 4, 9, NA, 1, 2)
vec2[Reduce(f = function(a,b) sum(a, b, na.rm = T), x = vec2, accumulate = TRUE, right = T) < 20]
##[1] 3 4 9 NA 1 2
I find the Reduce option to start from right (end of the integer vector), and hence not having to reverse it first, convenient.
edited 3 hours ago
answered 3 hours ago
Patrik_PPatrik_P
1,92721225
1,92721225
add a comment |
add a comment |
Hanna Dup is a new contributor. Be nice, and check out our Code of Conduct.
Hanna Dup is a new contributor. Be nice, and check out our Code of Conduct.
Hanna Dup is a new contributor. Be nice, and check out our Code of Conduct.
Hanna Dup is a new contributor. Be nice, and check out our Code of Conduct.
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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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%2f54212081%2fhow-to-keep-dropping-the-first-value-until-the-sum-of-the-vector-is-less-than-2%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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
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