我正在做R练习:
编写一个函数,将字符串拆分为字母并返回min&按字母顺序排列的最大字母数。
这是矢量:
cities <- c("New York", "Paris", "London", "Tokyo", "Rio de Janeiro", "Cape Town")
这是我写的代码:
first_and_last <- function(name){
name <- gsub (" ", "", name)
letters <- strsplit(name, split = "")
c(first = min(letters), last = max(letters))
}
然而,当我运行它时出错:
first_and_last(cities)
#Error in min(letters) (from #4) : invalid 'type' (list) of argument
请告诉我代码中缺少的内容?谢谢!
答案 0 :(得分:3)
首先,你的功能几乎是正确的。我已经包含了vapply()
个循环来执行min()
和max()
函数元素,然后返回结果的数据框。正如@Zheyuan Li指出你也可以使用sapply()
这是有效的,但我更喜欢在编写函数时避免使用sapply()
(参见Why is `vapply` safer than `sapply`?),尽管两者都能得到答案: - )
return_first_and_last <- function(name) {
name <- gsub (" ", "", name)
name <- strsplit(name, split = "")
first <- vapply(name, min, "")
last <- vapply(name, max, "")
data.frame(
first = first,
last = last
)
}
return_first_and_last(cities)
# first last
# 1 e Y
# 2 a s
# 3 d o
# 4 k y
# 5 a R
# 6 a w
一些注意事项:
return_first_and_last()
&#39; letters
是R中的内置对象,即使在本地功能环境中,重新分配这些内容通常也是一个坏主意。我一直只是替换name
,因为我们在功能之外并不需要这样做。min()
将返回小写版本,max()
将返回大写版本(即您的函数返回min
为a
,max
为Y
,即使还有小写y
。答案 1 :(得分:1)
我假设你想要按元素操作,即对于cities
的每个元素,按字母顺序提取第一个和最后一个字母。这就是你需要的:
first_and_last <- function(name){
name <- gsub (" ", "", name)
myName <- strsplit(name, split = "")
result <- t(sapply(myName, range)) ## use function `range`
rownames(result) <- name
colnames(result) <- c("first", "last")
return(result)
}
first_and_last(cities)
# first last
# New York "e" "Y"
# Paris "a" "s"
# London "d" "o"
# Tokyo "k" "y"
# Rio de Janeiro "a" "R"
# Cape Town "a" "w"
我使用了函数range()
。这将返回min
和max
。它是R function(x) c(min(x), max(x))
的内置实现。
<强>后续强>
谢谢,问题解决了。我在R学习在线课程。在他们的解决方案中,他们使用了以下代码。如果可能,请解释一下,这行代码意味着什么。特别是,双括号部分&#34; [[1]]&#34;:
letters <- strsplit(name, split = "")[[1]]
strsplit
返回一个列表。试试吧:
strsplit("Bath", split = "")
#[[1]]
#[1] "B" "a" "t" "h"
如果要访问角色向量,则需要[[1]]
:
strsplit("Bath", split = "")[[1]]
#[1] "B" "a" "t" "h"
只有使用矢量,您才能min
/ max
。例如:
min(strsplit("Bath",split=""))
#Error in min(strsplit("Bath", split = "")) :
# invalid 'type' (list) of argument
min(strsplit("Bath",split="")[[1]])
#[1] "a"
我相信您看到的在线示例只需要一个字符。如果你有一个矢量输入,如:
strsplit(c("Bath", "Bristol", "Cambridge"), split = "")
#[[1]]
#[1] "B" "a" "t" "h"
#[[2]]
#[1] "B" "r" "i" "s" "t" "o" "l"
#[[3]]
#[1] "C" "a" "m" "b" "r" "i" "d" "g" "e"
并且您希望为每个列表元素应用range
,sapply
将非常方便:
sapply(strsplit(c("Bath", "Bristol", "Cambridge"), split = ""), range)
# [,1] [,2] [,3]
#[1,] "a" "B" "a"
#[2,] "t" "t" "r"
上面的我的功能first_and_last
基于sapply
。然而,为了很好的演示,我已经转换了结果并给出了行/列名称。
天哪,我刚才意识到你已经在[[]]
2天前问过Double Bracket [[]] within a Function了。那么你为什么还要我解释呢?