Create a sequence between two letters
I want to create a sequence between two letters let's say "b"
and "f"
. So the output is
"b" "c" "d" "e" "f"
For numbers, we can do
2:6 #which gives output as
[1] 2 3 4 5 6
Is there an easy way to do this with letters as well?
I have gone through Generate a sequence of characters from 'A'-'Z'
but this produces all the letters and not sequence between specific letters.
My current solution is,
indx <- which(letters %in% c("b", "f"));
letters[indx[1] : indx[2]]
#[1] "b" "c" "d" "e" "f"
This works but I am curious if there is an easy way to do this or a function in any of the package that I have missed?
Note: I do not want letters[2:6]
as I do not know 2 and 6 beforehand. It could be between any two letters.
r character
add a comment |
I want to create a sequence between two letters let's say "b"
and "f"
. So the output is
"b" "c" "d" "e" "f"
For numbers, we can do
2:6 #which gives output as
[1] 2 3 4 5 6
Is there an easy way to do this with letters as well?
I have gone through Generate a sequence of characters from 'A'-'Z'
but this produces all the letters and not sequence between specific letters.
My current solution is,
indx <- which(letters %in% c("b", "f"));
letters[indx[1] : indx[2]]
#[1] "b" "c" "d" "e" "f"
This works but I am curious if there is an easy way to do this or a function in any of the package that I have missed?
Note: I do not want letters[2:6]
as I do not know 2 and 6 beforehand. It could be between any two letters.
r character
2
What defines your set of "letters"? Do you want the 26 lower-case letters of the Latin alphabet, or do you want the set of letters in the users current locale? Which could be the french, greek, russian, arabic or other alphabet?
– Spacedman
Nov 26 '18 at 8:33
@Spacedman yes, currently looking only for 26 letters from Latin alphabet.
– Ronak Shah
Nov 26 '18 at 8:50
"I do not want letters[2:6] as I do not know 2 and 6 beforehand." So I take it the reason you don't want to doletters[begin:end]
is that you want to generate it based on the limits being given as letters rather than numbers?
– Acccumulation
Nov 26 '18 at 23:18
@Acccumulation correct. I have input as letters and not numbers.
– Ronak Shah
Nov 27 '18 at 1:12
add a comment |
I want to create a sequence between two letters let's say "b"
and "f"
. So the output is
"b" "c" "d" "e" "f"
For numbers, we can do
2:6 #which gives output as
[1] 2 3 4 5 6
Is there an easy way to do this with letters as well?
I have gone through Generate a sequence of characters from 'A'-'Z'
but this produces all the letters and not sequence between specific letters.
My current solution is,
indx <- which(letters %in% c("b", "f"));
letters[indx[1] : indx[2]]
#[1] "b" "c" "d" "e" "f"
This works but I am curious if there is an easy way to do this or a function in any of the package that I have missed?
Note: I do not want letters[2:6]
as I do not know 2 and 6 beforehand. It could be between any two letters.
r character
I want to create a sequence between two letters let's say "b"
and "f"
. So the output is
"b" "c" "d" "e" "f"
For numbers, we can do
2:6 #which gives output as
[1] 2 3 4 5 6
Is there an easy way to do this with letters as well?
I have gone through Generate a sequence of characters from 'A'-'Z'
but this produces all the letters and not sequence between specific letters.
My current solution is,
indx <- which(letters %in% c("b", "f"));
letters[indx[1] : indx[2]]
#[1] "b" "c" "d" "e" "f"
This works but I am curious if there is an easy way to do this or a function in any of the package that I have missed?
Note: I do not want letters[2:6]
as I do not know 2 and 6 beforehand. It could be between any two letters.
r character
r character
edited Nov 26 '18 at 8:43
zx8754
29.4k76398
29.4k76398
asked Nov 26 '18 at 8:01
Ronak ShahRonak Shah
35.5k103856
35.5k103856
2
What defines your set of "letters"? Do you want the 26 lower-case letters of the Latin alphabet, or do you want the set of letters in the users current locale? Which could be the french, greek, russian, arabic or other alphabet?
– Spacedman
Nov 26 '18 at 8:33
@Spacedman yes, currently looking only for 26 letters from Latin alphabet.
– Ronak Shah
Nov 26 '18 at 8:50
"I do not want letters[2:6] as I do not know 2 and 6 beforehand." So I take it the reason you don't want to doletters[begin:end]
is that you want to generate it based on the limits being given as letters rather than numbers?
– Acccumulation
Nov 26 '18 at 23:18
@Acccumulation correct. I have input as letters and not numbers.
– Ronak Shah
Nov 27 '18 at 1:12
add a comment |
2
What defines your set of "letters"? Do you want the 26 lower-case letters of the Latin alphabet, or do you want the set of letters in the users current locale? Which could be the french, greek, russian, arabic or other alphabet?
– Spacedman
Nov 26 '18 at 8:33
@Spacedman yes, currently looking only for 26 letters from Latin alphabet.
– Ronak Shah
Nov 26 '18 at 8:50
"I do not want letters[2:6] as I do not know 2 and 6 beforehand." So I take it the reason you don't want to doletters[begin:end]
is that you want to generate it based on the limits being given as letters rather than numbers?
– Acccumulation
Nov 26 '18 at 23:18
@Acccumulation correct. I have input as letters and not numbers.
– Ronak Shah
Nov 27 '18 at 1:12
2
2
What defines your set of "letters"? Do you want the 26 lower-case letters of the Latin alphabet, or do you want the set of letters in the users current locale? Which could be the french, greek, russian, arabic or other alphabet?
– Spacedman
Nov 26 '18 at 8:33
What defines your set of "letters"? Do you want the 26 lower-case letters of the Latin alphabet, or do you want the set of letters in the users current locale? Which could be the french, greek, russian, arabic or other alphabet?
– Spacedman
Nov 26 '18 at 8:33
@Spacedman yes, currently looking only for 26 letters from Latin alphabet.
– Ronak Shah
Nov 26 '18 at 8:50
@Spacedman yes, currently looking only for 26 letters from Latin alphabet.
– Ronak Shah
Nov 26 '18 at 8:50
"I do not want letters[2:6] as I do not know 2 and 6 beforehand." So I take it the reason you don't want to do
letters[begin:end]
is that you want to generate it based on the limits being given as letters rather than numbers?– Acccumulation
Nov 26 '18 at 23:18
"I do not want letters[2:6] as I do not know 2 and 6 beforehand." So I take it the reason you don't want to do
letters[begin:end]
is that you want to generate it based on the limits being given as letters rather than numbers?– Acccumulation
Nov 26 '18 at 23:18
@Acccumulation correct. I have input as letters and not numbers.
– Ronak Shah
Nov 27 '18 at 1:12
@Acccumulation correct. I have input as letters and not numbers.
– Ronak Shah
Nov 27 '18 at 1:12
add a comment |
8 Answers
8
active
oldest
votes
This would be another base R option:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
add a comment |
You can create your own function:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
Usage:
"b" %:% "f"
# [1] "b" "c" "d" "e" "f"
"f" %:% "b"
# [1] "f" "e" "d" "c" "b"
"A" %:% "D"
# [1] "A" "B" "C" "D"
Ow, nice, didn't know about"multiple = TRUE"
option.
– zx8754
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makesintToUtf8
a very handy function.
– Sven Hohenstein
Nov 26 '18 at 8:11
Definitely better than my use ofraw
.
– 42-
Nov 26 '18 at 8:20
add a comment |
Another option with match
, seq
and do.call
:
letters[do.call(seq, as.list(match(c("b","f"), letters)))]
which gives:
[1] "b" "c" "d" "e" "f"
Making a function of this such that it works with both lower-case and upper-case letters:
char_seq <- function(lets) {
switch(all(grepl("[[:upper:]]", lets)) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
the output of this:
> char_seq(c("b","f"))
[1] "b" "c" "d" "e" "f"
> char_seq(c("B","F"))
[1] "B" "C" "D" "E" "F"
This function can be extended with checks on the correctness of the input:
char_seq <- function(lets) {
g <- grepl("[[:upper:]]", lets)
if(length(g) != 2) stop("Input is not of length 2")
if(sum(g) == 1) stop("Input does not have all lower-case or all upper-case letters")
switch(all(g) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
resulting in proper error-messages when the input is not correct:
> char_seq(c("B"))
Error in char_seq(c("B")) : Input is not of length 2
> char_seq(c("b","F"))
Error in char_seq(c("b", "F")) :
Input does not have all lower-case or all upper-case letters
add a comment |
Playing with UTF, something like:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
add a comment |
Perhaps using the raw versions of letters and then converting back to character could be used to define an infix function analogous to ":"
`%c:%` <- function(x,y) { strsplit( rawToChar(as.raw(
seq(as.numeric(charToRaw(x)), as.numeric(charToRaw(y))))), "" )[[1]]}
> 'a' %c:% 'g'
[1] "a" "b" "c" "d" "e" "f" "g"
I'm certainly not claiming this satisfies the request for "an easy way to do this" and I'm not even certain it would be more efficient, but it does introduce a couple of potentially useful functions.
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
1
I often find the process of locating conversion functions likecharToRaw
andrawToChar
difficult. Also in the list of functions I have trouble remembering are:intToUtf8
andchartr
,sfsmisc::AsciiToInt
,stringi::stri_enc_isascii
,stringi::stri_enc_toascii
. The last few I located by using??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my.Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.
– 42-
Dec 11 '18 at 18:20
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
add a comment |
Why not?
letters[which(letters == 'b') : which(letters == 'f')]
add a comment |
Iknow it is frowned upon, but here is an eval(parse(...))
solution
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
Usingeval
andparse
here is blatant abuse, sorry. You can implement the same logic without (e.g. withdo.call
), although the logic itself is also needlessly convoluted.
– Konrad Rudolph
Nov 27 '18 at 10:28
add a comment |
First things first: your code
which(letters %in% c("b", "f"))
Is a valid but convoluted way of writing
match(c('b', 'f'), letters)
(Why “convoluted”? Because %in%
is a wrapper around match
for a specific use-case, which explicitly turns the numeric index into a logical value, i.e. the inverse operation of which
.)
Next, you can of course use the result and convert it into a range via idx[1L] : idx[2L]
and there’s nothing wrong with that in this case. But R has an idiomatic way of expressing the concept of calling a function using a vector as its parameters: do.call
:
do.call(`:`, as.list(match(c('b', 'f'), letters)))
Or, equivalently:
do.call(seq, as.list(match(c('b', 'f'), letters)))
{purrr} allows us to do the same without the as.list
:
purrr::invoke(seq, match(c('b', 'f'), letters))
And, finally, we subset:
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
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%2f53476833%2fcreate-a-sequence-between-two-letters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
This would be another base R option:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
add a comment |
This would be another base R option:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
add a comment |
This would be another base R option:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
This would be another base R option:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
answered Nov 26 '18 at 9:08
r.user.05aprr.user.05apr
2,0912723
2,0912723
add a comment |
add a comment |
You can create your own function:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
Usage:
"b" %:% "f"
# [1] "b" "c" "d" "e" "f"
"f" %:% "b"
# [1] "f" "e" "d" "c" "b"
"A" %:% "D"
# [1] "A" "B" "C" "D"
Ow, nice, didn't know about"multiple = TRUE"
option.
– zx8754
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makesintToUtf8
a very handy function.
– Sven Hohenstein
Nov 26 '18 at 8:11
Definitely better than my use ofraw
.
– 42-
Nov 26 '18 at 8:20
add a comment |
You can create your own function:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
Usage:
"b" %:% "f"
# [1] "b" "c" "d" "e" "f"
"f" %:% "b"
# [1] "f" "e" "d" "c" "b"
"A" %:% "D"
# [1] "A" "B" "C" "D"
Ow, nice, didn't know about"multiple = TRUE"
option.
– zx8754
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makesintToUtf8
a very handy function.
– Sven Hohenstein
Nov 26 '18 at 8:11
Definitely better than my use ofraw
.
– 42-
Nov 26 '18 at 8:20
add a comment |
You can create your own function:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
Usage:
"b" %:% "f"
# [1] "b" "c" "d" "e" "f"
"f" %:% "b"
# [1] "f" "e" "d" "c" "b"
"A" %:% "D"
# [1] "A" "B" "C" "D"
You can create your own function:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
Usage:
"b" %:% "f"
# [1] "b" "c" "d" "e" "f"
"f" %:% "b"
# [1] "f" "e" "d" "c" "b"
"A" %:% "D"
# [1] "A" "B" "C" "D"
edited Nov 26 '18 at 8:10
zx8754
29.4k76398
29.4k76398
answered Nov 26 '18 at 8:06
Sven HohensteinSven Hohenstein
65.4k1298130
65.4k1298130
Ow, nice, didn't know about"multiple = TRUE"
option.
– zx8754
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makesintToUtf8
a very handy function.
– Sven Hohenstein
Nov 26 '18 at 8:11
Definitely better than my use ofraw
.
– 42-
Nov 26 '18 at 8:20
add a comment |
Ow, nice, didn't know about"multiple = TRUE"
option.
– zx8754
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makesintToUtf8
a very handy function.
– Sven Hohenstein
Nov 26 '18 at 8:11
Definitely better than my use ofraw
.
– 42-
Nov 26 '18 at 8:20
Ow, nice, didn't know about
"multiple = TRUE"
option.– zx8754
Nov 26 '18 at 8:11
Ow, nice, didn't know about
"multiple = TRUE"
option.– zx8754
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makes
intToUtf8
a very handy function.– Sven Hohenstein
Nov 26 '18 at 8:11
@zx8754 Yes, this parameter makes
intToUtf8
a very handy function.– Sven Hohenstein
Nov 26 '18 at 8:11
Definitely better than my use of
raw
.– 42-
Nov 26 '18 at 8:20
Definitely better than my use of
raw
.– 42-
Nov 26 '18 at 8:20
add a comment |
Another option with match
, seq
and do.call
:
letters[do.call(seq, as.list(match(c("b","f"), letters)))]
which gives:
[1] "b" "c" "d" "e" "f"
Making a function of this such that it works with both lower-case and upper-case letters:
char_seq <- function(lets) {
switch(all(grepl("[[:upper:]]", lets)) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
the output of this:
> char_seq(c("b","f"))
[1] "b" "c" "d" "e" "f"
> char_seq(c("B","F"))
[1] "B" "C" "D" "E" "F"
This function can be extended with checks on the correctness of the input:
char_seq <- function(lets) {
g <- grepl("[[:upper:]]", lets)
if(length(g) != 2) stop("Input is not of length 2")
if(sum(g) == 1) stop("Input does not have all lower-case or all upper-case letters")
switch(all(g) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
resulting in proper error-messages when the input is not correct:
> char_seq(c("B"))
Error in char_seq(c("B")) : Input is not of length 2
> char_seq(c("b","F"))
Error in char_seq(c("b", "F")) :
Input does not have all lower-case or all upper-case letters
add a comment |
Another option with match
, seq
and do.call
:
letters[do.call(seq, as.list(match(c("b","f"), letters)))]
which gives:
[1] "b" "c" "d" "e" "f"
Making a function of this such that it works with both lower-case and upper-case letters:
char_seq <- function(lets) {
switch(all(grepl("[[:upper:]]", lets)) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
the output of this:
> char_seq(c("b","f"))
[1] "b" "c" "d" "e" "f"
> char_seq(c("B","F"))
[1] "B" "C" "D" "E" "F"
This function can be extended with checks on the correctness of the input:
char_seq <- function(lets) {
g <- grepl("[[:upper:]]", lets)
if(length(g) != 2) stop("Input is not of length 2")
if(sum(g) == 1) stop("Input does not have all lower-case or all upper-case letters")
switch(all(g) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
resulting in proper error-messages when the input is not correct:
> char_seq(c("B"))
Error in char_seq(c("B")) : Input is not of length 2
> char_seq(c("b","F"))
Error in char_seq(c("b", "F")) :
Input does not have all lower-case or all upper-case letters
add a comment |
Another option with match
, seq
and do.call
:
letters[do.call(seq, as.list(match(c("b","f"), letters)))]
which gives:
[1] "b" "c" "d" "e" "f"
Making a function of this such that it works with both lower-case and upper-case letters:
char_seq <- function(lets) {
switch(all(grepl("[[:upper:]]", lets)) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
the output of this:
> char_seq(c("b","f"))
[1] "b" "c" "d" "e" "f"
> char_seq(c("B","F"))
[1] "B" "C" "D" "E" "F"
This function can be extended with checks on the correctness of the input:
char_seq <- function(lets) {
g <- grepl("[[:upper:]]", lets)
if(length(g) != 2) stop("Input is not of length 2")
if(sum(g) == 1) stop("Input does not have all lower-case or all upper-case letters")
switch(all(g) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
resulting in proper error-messages when the input is not correct:
> char_seq(c("B"))
Error in char_seq(c("B")) : Input is not of length 2
> char_seq(c("b","F"))
Error in char_seq(c("b", "F")) :
Input does not have all lower-case or all upper-case letters
Another option with match
, seq
and do.call
:
letters[do.call(seq, as.list(match(c("b","f"), letters)))]
which gives:
[1] "b" "c" "d" "e" "f"
Making a function of this such that it works with both lower-case and upper-case letters:
char_seq <- function(lets) {
switch(all(grepl("[[:upper:]]", lets)) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
the output of this:
> char_seq(c("b","f"))
[1] "b" "c" "d" "e" "f"
> char_seq(c("B","F"))
[1] "B" "C" "D" "E" "F"
This function can be extended with checks on the correctness of the input:
char_seq <- function(lets) {
g <- grepl("[[:upper:]]", lets)
if(length(g) != 2) stop("Input is not of length 2")
if(sum(g) == 1) stop("Input does not have all lower-case or all upper-case letters")
switch(all(g) + 1L,
letters[do.call(seq, as.list(match(lets, letters)))],
LETTERS[do.call(seq, as.list(match(lets, LETTERS)))])
}
resulting in proper error-messages when the input is not correct:
> char_seq(c("B"))
Error in char_seq(c("B")) : Input is not of length 2
> char_seq(c("b","F"))
Error in char_seq(c("b", "F")) :
Input does not have all lower-case or all upper-case letters
edited Nov 26 '18 at 9:15
answered Nov 26 '18 at 8:24
JaapJaap
55.7k20119132
55.7k20119132
add a comment |
add a comment |
Playing with UTF, something like:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
add a comment |
Playing with UTF, something like:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
add a comment |
Playing with UTF, something like:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
Playing with UTF, something like:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
edited Nov 26 '18 at 8:10
answered Nov 26 '18 at 8:05
zx8754zx8754
29.4k76398
29.4k76398
add a comment |
add a comment |
Perhaps using the raw versions of letters and then converting back to character could be used to define an infix function analogous to ":"
`%c:%` <- function(x,y) { strsplit( rawToChar(as.raw(
seq(as.numeric(charToRaw(x)), as.numeric(charToRaw(y))))), "" )[[1]]}
> 'a' %c:% 'g'
[1] "a" "b" "c" "d" "e" "f" "g"
I'm certainly not claiming this satisfies the request for "an easy way to do this" and I'm not even certain it would be more efficient, but it does introduce a couple of potentially useful functions.
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
1
I often find the process of locating conversion functions likecharToRaw
andrawToChar
difficult. Also in the list of functions I have trouble remembering are:intToUtf8
andchartr
,sfsmisc::AsciiToInt
,stringi::stri_enc_isascii
,stringi::stri_enc_toascii
. The last few I located by using??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my.Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.
– 42-
Dec 11 '18 at 18:20
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
add a comment |
Perhaps using the raw versions of letters and then converting back to character could be used to define an infix function analogous to ":"
`%c:%` <- function(x,y) { strsplit( rawToChar(as.raw(
seq(as.numeric(charToRaw(x)), as.numeric(charToRaw(y))))), "" )[[1]]}
> 'a' %c:% 'g'
[1] "a" "b" "c" "d" "e" "f" "g"
I'm certainly not claiming this satisfies the request for "an easy way to do this" and I'm not even certain it would be more efficient, but it does introduce a couple of potentially useful functions.
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
1
I often find the process of locating conversion functions likecharToRaw
andrawToChar
difficult. Also in the list of functions I have trouble remembering are:intToUtf8
andchartr
,sfsmisc::AsciiToInt
,stringi::stri_enc_isascii
,stringi::stri_enc_toascii
. The last few I located by using??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my.Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.
– 42-
Dec 11 '18 at 18:20
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
add a comment |
Perhaps using the raw versions of letters and then converting back to character could be used to define an infix function analogous to ":"
`%c:%` <- function(x,y) { strsplit( rawToChar(as.raw(
seq(as.numeric(charToRaw(x)), as.numeric(charToRaw(y))))), "" )[[1]]}
> 'a' %c:% 'g'
[1] "a" "b" "c" "d" "e" "f" "g"
I'm certainly not claiming this satisfies the request for "an easy way to do this" and I'm not even certain it would be more efficient, but it does introduce a couple of potentially useful functions.
Perhaps using the raw versions of letters and then converting back to character could be used to define an infix function analogous to ":"
`%c:%` <- function(x,y) { strsplit( rawToChar(as.raw(
seq(as.numeric(charToRaw(x)), as.numeric(charToRaw(y))))), "" )[[1]]}
> 'a' %c:% 'g'
[1] "a" "b" "c" "d" "e" "f" "g"
I'm certainly not claiming this satisfies the request for "an easy way to do this" and I'm not even certain it would be more efficient, but it does introduce a couple of potentially useful functions.
edited Nov 26 '18 at 8:16
answered Nov 26 '18 at 8:03
42-42-
212k15251398
212k15251398
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
1
I often find the process of locating conversion functions likecharToRaw
andrawToChar
difficult. Also in the list of functions I have trouble remembering are:intToUtf8
andchartr
,sfsmisc::AsciiToInt
,stringi::stri_enc_isascii
,stringi::stri_enc_toascii
. The last few I located by using??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my.Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.
– 42-
Dec 11 '18 at 18:20
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
add a comment |
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
1
I often find the process of locating conversion functions likecharToRaw
andrawToChar
difficult. Also in the list of functions I have trouble remembering are:intToUtf8
andchartr
,sfsmisc::AsciiToInt
,stringi::stri_enc_isascii
,stringi::stri_enc_toascii
. The last few I located by using??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my.Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.
– 42-
Dec 11 '18 at 18:20
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
"it does introduce a couple of potentially useful functions" Can you develop?
– J.Gourlay
Dec 11 '18 at 14:02
1
1
I often find the process of locating conversion functions like
charToRaw
and rawToChar
difficult. Also in the list of functions I have trouble remembering are: intToUtf8
and chartr
, sfsmisc::AsciiToInt
, stringi::stri_enc_isascii
, stringi::stri_enc_toascii
. The last few I located by using ??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my .Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.– 42-
Dec 11 '18 at 18:20
I often find the process of locating conversion functions like
charToRaw
and rawToChar
difficult. Also in the list of functions I have trouble remembering are: intToUtf8
and chartr
, sfsmisc::AsciiToInt
, stringi::stri_enc_isascii
, stringi::stri_enc_toascii
. The last few I located by using ??ascii
. I think there are a few other utility functions that I sometimes can locate, but not at this moment cannot. I had a lsit in my .Rprofile
file on my "regular" computer but I'm now converting from Mac to Linux and don't have it running.– 42-
Dec 11 '18 at 18:20
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
I see your point, having myself difficulties to remember functions that I've used months ago. Thanks!
– J.Gourlay
Dec 12 '18 at 8:52
add a comment |
Why not?
letters[which(letters == 'b') : which(letters == 'f')]
add a comment |
Why not?
letters[which(letters == 'b') : which(letters == 'f')]
add a comment |
Why not?
letters[which(letters == 'b') : which(letters == 'f')]
Why not?
letters[which(letters == 'b') : which(letters == 'f')]
answered Nov 26 '18 at 9:55
Anastasiya-Romanova 秀Anastasiya-Romanova 秀
1,9361231
1,9361231
add a comment |
add a comment |
Iknow it is frowned upon, but here is an eval(parse(...))
solution
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
Usingeval
andparse
here is blatant abuse, sorry. You can implement the same logic without (e.g. withdo.call
), although the logic itself is also needlessly convoluted.
– Konrad Rudolph
Nov 27 '18 at 10:28
add a comment |
Iknow it is frowned upon, but here is an eval(parse(...))
solution
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
Usingeval
andparse
here is blatant abuse, sorry. You can implement the same logic without (e.g. withdo.call
), although the logic itself is also needlessly convoluted.
– Konrad Rudolph
Nov 27 '18 at 10:28
add a comment |
Iknow it is frowned upon, but here is an eval(parse(...))
solution
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
Iknow it is frowned upon, but here is an eval(parse(...))
solution
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
answered Nov 26 '18 at 8:23
SotosSotos
29k51640
29k51640
Usingeval
andparse
here is blatant abuse, sorry. You can implement the same logic without (e.g. withdo.call
), although the logic itself is also needlessly convoluted.
– Konrad Rudolph
Nov 27 '18 at 10:28
add a comment |
Usingeval
andparse
here is blatant abuse, sorry. You can implement the same logic without (e.g. withdo.call
), although the logic itself is also needlessly convoluted.
– Konrad Rudolph
Nov 27 '18 at 10:28
Using
eval
and parse
here is blatant abuse, sorry. You can implement the same logic without (e.g. with do.call
), although the logic itself is also needlessly convoluted.– Konrad Rudolph
Nov 27 '18 at 10:28
Using
eval
and parse
here is blatant abuse, sorry. You can implement the same logic without (e.g. with do.call
), although the logic itself is also needlessly convoluted.– Konrad Rudolph
Nov 27 '18 at 10:28
add a comment |
First things first: your code
which(letters %in% c("b", "f"))
Is a valid but convoluted way of writing
match(c('b', 'f'), letters)
(Why “convoluted”? Because %in%
is a wrapper around match
for a specific use-case, which explicitly turns the numeric index into a logical value, i.e. the inverse operation of which
.)
Next, you can of course use the result and convert it into a range via idx[1L] : idx[2L]
and there’s nothing wrong with that in this case. But R has an idiomatic way of expressing the concept of calling a function using a vector as its parameters: do.call
:
do.call(`:`, as.list(match(c('b', 'f'), letters)))
Or, equivalently:
do.call(seq, as.list(match(c('b', 'f'), letters)))
{purrr} allows us to do the same without the as.list
:
purrr::invoke(seq, match(c('b', 'f'), letters))
And, finally, we subset:
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
add a comment |
First things first: your code
which(letters %in% c("b", "f"))
Is a valid but convoluted way of writing
match(c('b', 'f'), letters)
(Why “convoluted”? Because %in%
is a wrapper around match
for a specific use-case, which explicitly turns the numeric index into a logical value, i.e. the inverse operation of which
.)
Next, you can of course use the result and convert it into a range via idx[1L] : idx[2L]
and there’s nothing wrong with that in this case. But R has an idiomatic way of expressing the concept of calling a function using a vector as its parameters: do.call
:
do.call(`:`, as.list(match(c('b', 'f'), letters)))
Or, equivalently:
do.call(seq, as.list(match(c('b', 'f'), letters)))
{purrr} allows us to do the same without the as.list
:
purrr::invoke(seq, match(c('b', 'f'), letters))
And, finally, we subset:
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
add a comment |
First things first: your code
which(letters %in% c("b", "f"))
Is a valid but convoluted way of writing
match(c('b', 'f'), letters)
(Why “convoluted”? Because %in%
is a wrapper around match
for a specific use-case, which explicitly turns the numeric index into a logical value, i.e. the inverse operation of which
.)
Next, you can of course use the result and convert it into a range via idx[1L] : idx[2L]
and there’s nothing wrong with that in this case. But R has an idiomatic way of expressing the concept of calling a function using a vector as its parameters: do.call
:
do.call(`:`, as.list(match(c('b', 'f'), letters)))
Or, equivalently:
do.call(seq, as.list(match(c('b', 'f'), letters)))
{purrr} allows us to do the same without the as.list
:
purrr::invoke(seq, match(c('b', 'f'), letters))
And, finally, we subset:
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
First things first: your code
which(letters %in% c("b", "f"))
Is a valid but convoluted way of writing
match(c('b', 'f'), letters)
(Why “convoluted”? Because %in%
is a wrapper around match
for a specific use-case, which explicitly turns the numeric index into a logical value, i.e. the inverse operation of which
.)
Next, you can of course use the result and convert it into a range via idx[1L] : idx[2L]
and there’s nothing wrong with that in this case. But R has an idiomatic way of expressing the concept of calling a function using a vector as its parameters: do.call
:
do.call(`:`, as.list(match(c('b', 'f'), letters)))
Or, equivalently:
do.call(seq, as.list(match(c('b', 'f'), letters)))
{purrr} allows us to do the same without the as.list
:
purrr::invoke(seq, match(c('b', 'f'), letters))
And, finally, we subset:
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
edited Nov 27 '18 at 10:42
answered Nov 27 '18 at 10:34
Konrad RudolphKonrad Rudolph
395k1017821025
395k1017821025
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%2f53476833%2fcreate-a-sequence-between-two-letters%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
2
What defines your set of "letters"? Do you want the 26 lower-case letters of the Latin alphabet, or do you want the set of letters in the users current locale? Which could be the french, greek, russian, arabic or other alphabet?
– Spacedman
Nov 26 '18 at 8:33
@Spacedman yes, currently looking only for 26 letters from Latin alphabet.
– Ronak Shah
Nov 26 '18 at 8:50
"I do not want letters[2:6] as I do not know 2 and 6 beforehand." So I take it the reason you don't want to do
letters[begin:end]
is that you want to generate it based on the limits being given as letters rather than numbers?– Acccumulation
Nov 26 '18 at 23:18
@Acccumulation correct. I have input as letters and not numbers.
– Ronak Shah
Nov 27 '18 at 1:12