R 在两个字母之间创建一个序列
我想在两个字母之间创建一个序列,比如说R 在两个字母之间创建一个序列,r,character,R,Character,我想在两个字母之间创建一个序列,比如说“b”和“f”。所以输出是 "b" "c" "d" "e" "f" 对于数字,我们可以这样做 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"
“b”
和“f”
。所以输出是
"b" "c" "d" "e" "f"
对于数字,我们可以这样做
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"
indx也许使用字母的原始版本,然后再转换回字符,可以用来定义类似于“:”
`%c:%%`a'%c:%%'g'
[1] “a”“b”“c”“d”“e”“f”“g”
我当然不是说这满足了“一种简单的方法”的要求,我甚至不确定它是否会更有效,但它确实引入了一些潜在的有用功能。使用UTF,比如:
intToUtf8(utf8ToInt("b"):utf8ToInt("f"), multiple = TRUE)
# [1] "b" "c" "d" "e" "f"
您可以创建自己的函数:
`%:%` <- function(l, r) {
intToUtf8(seq(utf8ToInt(l), utf8ToInt(r)), multiple = TRUE)
}
我知道这是不赞成的,但这里有一个eval(parse(…)
解决方案
LETTERS[eval(parse(text = paste(which(LETTERS %in% c('B', 'F')), collapse = ':')))]
#[1] "B" "C" "D" "E" "F"
另一个带有match
、seq
和do.call的选项:
letters[do.call(seq, as.list(match(c("b","f"), 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)))])
}
可通过检查输入的正确性来扩展此功能:
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)))])
}
这将是另一个基本R选项:
letters[(letters >= "b") & (letters <= "f")]
# [1] "b" "c" "d" "e" "f"
字母[(字母>=“b”)和(字母为什么不
letters[which(letters == 'b') : which(letters == 'f')]
第一件事:你的代码
which(letters %in% c("b", "f"))
是一种有效但复杂的写作方式
match(c('b', 'f'), letters)
(为什么要“卷积”?因为%
中的%是特定用例的匹配
的包装,它显式地将数字索引转换为逻辑值,即的逆运算,它
)
接下来,您当然可以使用结果并通过idx[1L]:idx[2L]
将其转换为一个范围,在这种情况下,这没有什么错。但是R有一种惯用的方式来表达使用向量作为其参数调用函数的概念:
或者,相当于:
do.call(seq, as.list(match(c('b', 'f'), letters)))
{purrr}允许我们在没有as.list
的情况下执行相同的操作:
purrr::invoke(seq, match(c('b', 'f'), letters))
最后,我们将:
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
您可以使用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"
或者使用匹配
letters[match("b", letters) : match("f", letters)]
#[1] "b" "c" "d" "e" "f"
噢,尼斯,我不知道“multiple=TRUE”
选项。@zx8754是的,这个参数使intToUtf8
成为一个非常方便的函数。肯定比我使用raw
要好。什么定义了你的“字母集”?您想要拉丁字母表中的26个小写字母,还是用户当前语言环境中的一组字母?可以是法语、希腊语、俄语、阿拉伯语或其他字母?@Spacedman是的,目前只查找拉丁字母表中的26个字母。“我不想要字母[2:6],因为我事先不知道2和6。”所以我认为这是你不想写字母[begin:end]的原因
是基于以字母而不是数字形式给出的限制生成的吗?@accumulation正确。我输入的是字母而不是数字。使用eval
和parse
这是明显的滥用,抱歉。您可以在没有(例如使用do.call
)的情况下实现相同的逻辑,尽管逻辑本身也不必要地复杂。“它确实引入了一些潜在的有用函数”你能开发吗?我经常发现像charToRaw
和rawToChar
这样的转换函数的定位过程很困难。在我记忆困难的函数列表中还有:intToUtf8
和chartr
,sfsmisiscioit
,stringi::stri_enc isascii
,stringi::stri_enc_toascii
。最后几个我是通过使用?ascii
定位的。我认为还有一些其他实用程序函数有时可以定位,但目前还不能定位。我在“常规”的.Rprofile
文件中有一个lsit电脑,但我现在正在从Mac转换到Linux,并且没有运行它。我明白你的意思,我很难记住几个月前使用过的函数。谢谢!
do.call(seq, as.list(match(c('b', 'f'), letters)))
purrr::invoke(seq, match(c('b', 'f'), letters))
letters[purrr::invoke(seq, match(c('b', 'f'), letters))]
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(grep("[b-f]", letters, value = TRUE))
#[1] "f" "e" "d" "c" "b"
letters[match("b", letters) : match("f", letters)]
#[1] "b" "c" "d" "e" "f"