我想在两个字母之间创建一个序列,比如[
"H":[
{
"id": 2134,
"name": "Happy Brithday",
"artist": "Paul Anka",
"isFaved": false,
"code": "380dj0a"
},
{
"id": 38304,
"name": "How can i stop loving you",
"artist": "Savage Garden",
"isFaved": false,
"code": "kkdj0a"
}
]
]
和"b"
。所以输出是
"f"
对于数字,我们可以做到
"b" "c" "d" "e" "f"
有没有一种简便的方法可以对字母进行处理?
我经历了Generate a sequence of characters from 'A'-'Z' ,但这会产生所有字母,而不是特定字母之间的顺序。
我当前的解决方案是
2:6 #which gives output as
[1] 2 3 4 5 6
这行得通,但是我很好奇是否有一种简单的方法可以执行此操作,或者是否可以在我错过的任何软件包中使用该功能?
注意:我不想要indx <- which(letters %in% c("b", "f"));
letters[indx[1] : indx[2]]
#[1] "b" "c" "d" "e" "f"
,因为我事先不知道2和6。可以在任何两个字母之间。
答案 0 :(得分:26)
这将是另一个基本的R选项:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
答案 1 :(得分:17)
您可以创建自己的函数:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
用法:
"b" %:% "f"
# [1] "b" "c" "d" "e" "f"
"f" %:% "b"
# [1] "f" "e" "d" "c" "b"
"A" %:% "D"
# [1] "A" "B" "C" "D"
答案 2 :(得分:12)
带有match
,seq
和do.call
的另一个选项:
letters[do.call(seq, as.list(match(c("b","f"), letters)))]
给出:
[1] "b" "c" "d" "e" "f"
具有此功能,使其可以同时使用小写和大写字母:
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)))])
}
此输出:
> char_seq(c("b","f")) [1] "b" "c" "d" "e" "f" > char_seq(c("B","F")) [1] "B" "C" "D" "E" "F"
可以通过检查输入的正确性来扩展此功能:
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)))])
}
输入不正确时会导致正确的错误消息:
> 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
答案 3 :(得分:10)
使用UTF播放,类似:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
答案 4 :(得分:8)
也许可以使用字母的原始版本然后转换回字符来定义类似于":"
的中缀函数
`%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"
我当然不是说这可以满足“一种简单的方法”的要求,甚至不确定它是否会更有效,但是它确实引入了一些可能有用的功能。
答案 5 :(得分:8)
为什么不呢?
letters[which(letters == 'b') : which(letters == 'f')]
答案 6 :(得分:6)
不知道这是一种皱纹,但这是一个eval(parse(...))
解决方案
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
答案 7 :(得分:1)
第一件事:您的代码
which(letters %in% c("b", "f"))
是一种有效的但令人费解的写作方式
match(c('b', 'f'), letters)
(为什么“卷积”?因为%in%
是特定用例的match
的包装器,因此将数字索引显式转换为逻辑值,即{{1的逆运算) }}。
接下来,您当然可以使用结果,并通过which
将其转换为范围,在这种情况下,这没有任何问题。但是R有一种惯用的方式来表达使用向量作为参数的函数调用概念:microservices:
idx[1L] : idx[2L]
或者,等效地:
do.call(`:`, as.list(match(c('b', 'f'), letters)))
{purrr}允许我们执行以下操作而无需使用do.call(seq, as.list(match(c('b', 'f'), letters)))
:
as.list
最后,我们子集:
purrr::invoke(seq, match(c('b', 'f'), letters))
答案 8 :(得分:1)
您可以使用grep
和letters
以及模式[b-f]
。
grep("[b-f]", letters, value = TRUE)
#[1] "b" "c" "d" "e" "f"
letters[grep("[b-f]", letters)]
#[1] "b" "c" "d" "e" "f"
letters[grepl("[b-f]", letters)]
#[1] "b" "c" "d" "e" "f"
对于递减的序列,您可以另外使用rev
rev(grep("[b-f]", letters, value = TRUE))
#[1] "f" "e" "d" "c" "b"
或使用match
。
letters[match("b", letters) : match("f", letters)]
#[1] "b" "c" "d" "e" "f"