Cut elements from the beginning and end of an R vector
For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)
vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)
I did this by looping from the beginning and end, and masking out the unwanted elements.
mask <- rep(TRUE, length(vec))
# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}
# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}
cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4
This works, but I wonder if there is a more efficient way to do this, avoiding the loops.
r
add a comment |
For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)
vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)
I did this by looping from the beginning and end, and masking out the unwanted elements.
mask <- rep(TRUE, length(vec))
# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}
# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}
cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4
This works, but I wonder if there is a more efficient way to do this, avoiding the loops.
r
Maybe this: stackoverflow.com/questions/32581950/…
– Andreas Neumeier
Dec 30 '18 at 17:15
This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.
– Ric S
Dec 30 '18 at 17:32
add a comment |
For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)
vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)
I did this by looping from the beginning and end, and masking out the unwanted elements.
mask <- rep(TRUE, length(vec))
# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}
# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}
cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4
This works, but I wonder if there is a more efficient way to do this, avoiding the loops.
r
For time series analysis I handle data that often contains leading and trailing zero elements. In this example, there are 3 zeros at the beginning an 2 at the end. I want to get rid of these elements, and filter for the contents in the middle (that also may contain zeros)
vec <- c(0, 0, 0, 1, 2, 0, 3, 4, 0, 0)
I did this by looping from the beginning and end, and masking out the unwanted elements.
mask <- rep(TRUE, length(vec))
# from begin
i <- 1
while(vec[i] == 0 && i <= length(vec)) {
mask[i] <- FALSE
i <- i+1
}
# from end
i <- length(vec)
while(i >= 1 && vec[i] == 0) {
mask[i] <- FALSE
i <- i-1
}
cleanvec <- vec[mask]
cleanvec
[1] 1 2 0 3 4
This works, but I wonder if there is a more efficient way to do this, avoiding the loops.
r
r
asked Dec 30 '18 at 17:13
wotuzu17wotuzu17
977
977
Maybe this: stackoverflow.com/questions/32581950/…
– Andreas Neumeier
Dec 30 '18 at 17:15
This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.
– Ric S
Dec 30 '18 at 17:32
add a comment |
Maybe this: stackoverflow.com/questions/32581950/…
– Andreas Neumeier
Dec 30 '18 at 17:15
This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.
– Ric S
Dec 30 '18 at 17:32
Maybe this: stackoverflow.com/questions/32581950/…
– Andreas Neumeier
Dec 30 '18 at 17:15
Maybe this: stackoverflow.com/questions/32581950/…
– Andreas Neumeier
Dec 30 '18 at 17:15
This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.
– Ric S
Dec 30 '18 at 17:32
This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.
– Ric S
Dec 30 '18 at 17:32
add a comment |
3 Answers
3
active
oldest
votes
vec[ min(which(vec != 0)) : max(which(vec != 0)) ]
Basically the which(vec != 0)
part gives the positions of the numbers that are different from 0, and then you take the min and max of them.
1
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
add a comment |
We could use the range
and Reduce
to get the sequence
vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4
add a comment |
Take the cumsum
forward and backward of abs(vec)
and keep only elements > 0. if it were known that all elements of vec
were non-negative, as in the question, then we could optionally omit abs
.
vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
## [1] 1 2 0 3 4
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%2f53979740%2fcut-elements-from-the-beginning-and-end-of-an-r-vector%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
vec[ min(which(vec != 0)) : max(which(vec != 0)) ]
Basically the which(vec != 0)
part gives the positions of the numbers that are different from 0, and then you take the min and max of them.
1
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
add a comment |
vec[ min(which(vec != 0)) : max(which(vec != 0)) ]
Basically the which(vec != 0)
part gives the positions of the numbers that are different from 0, and then you take the min and max of them.
1
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
add a comment |
vec[ min(which(vec != 0)) : max(which(vec != 0)) ]
Basically the which(vec != 0)
part gives the positions of the numbers that are different from 0, and then you take the min and max of them.
vec[ min(which(vec != 0)) : max(which(vec != 0)) ]
Basically the which(vec != 0)
part gives the positions of the numbers that are different from 0, and then you take the min and max of them.
answered Dec 30 '18 at 17:23
Ric SRic S
664318
664318
1
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
add a comment |
1
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
1
1
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
good solution, but this will cause an error if vec consists only of zeros.
– wotuzu17
Dec 30 '18 at 18:26
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
You are right, maybe you can set an if statement to check whether that conditions occurs.
– Ric S
Dec 30 '18 at 19:15
add a comment |
We could use the range
and Reduce
to get the sequence
vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4
add a comment |
We could use the range
and Reduce
to get the sequence
vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4
add a comment |
We could use the range
and Reduce
to get the sequence
vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4
We could use the range
and Reduce
to get the sequence
vec[Reduce(`:`, range(which(vec != 0)))]
#[1] 1 2 0 3 4
answered Dec 30 '18 at 18:46
akrunakrun
405k13196269
405k13196269
add a comment |
add a comment |
Take the cumsum
forward and backward of abs(vec)
and keep only elements > 0. if it were known that all elements of vec
were non-negative, as in the question, then we could optionally omit abs
.
vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
## [1] 1 2 0 3 4
add a comment |
Take the cumsum
forward and backward of abs(vec)
and keep only elements > 0. if it were known that all elements of vec
were non-negative, as in the question, then we could optionally omit abs
.
vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
## [1] 1 2 0 3 4
add a comment |
Take the cumsum
forward and backward of abs(vec)
and keep only elements > 0. if it were known that all elements of vec
were non-negative, as in the question, then we could optionally omit abs
.
vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
## [1] 1 2 0 3 4
Take the cumsum
forward and backward of abs(vec)
and keep only elements > 0. if it were known that all elements of vec
were non-negative, as in the question, then we could optionally omit abs
.
vec[cumsum(abs(vec)) > 0 & rev(cumsum(rev(abs(vec)))) > 0]
## [1] 1 2 0 3 4
edited Dec 30 '18 at 23:52
answered Dec 30 '18 at 22:42
G. GrothendieckG. Grothendieck
147k9130235
147k9130235
add a comment |
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%2f53979740%2fcut-elements-from-the-beginning-and-end-of-an-r-vector%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
Maybe this: stackoverflow.com/questions/32581950/…
– Andreas Neumeier
Dec 30 '18 at 17:15
This is referred to lists, not vectors; furthermore, it removes all zeros in the list elements, whereas here the question asks for removing zeros at the beginning and at the end of the vector.
– Ric S
Dec 30 '18 at 17:32