我编写了以下代码:
NovelID <- NULL
x <- 1
while(x < 25) {
if(length(NovelID) < 25) {
NovelID <- c(NovelID, SalesList$BookID[SalesList$BookType[] == "Novel"])
x <- x + 1
}
}
因此,我有一个名为SalesList的数据集,它有多个列,但我只对名为BookType和BookID的列感兴趣。BookType列有多种类型的书(科幻、宗教、小说等),每一种书在BookID列中都有相应的书id。我想要前25本类型为"小说"的书的书号。输入新形成的名为NovelID的向量。当我运行代码时(如上所述),代码继续运行,所以我不得不强制停止它。之后,我检查了NovelID的长度,它的长度等于数据集中类型为"novel"的图书的数量。(等于121)。我不能让循环一个接一个地工作,因为在第二次进入循环后它会卡住,因为现在NovelID的长度已经变成121(因此超过了25的限制)。就我而言,我的错误在于我试图将NovelID与数据结合在一起的代码部分,更具体地说,是在索引部分。然而,我不确定输入什么代码来获得我想要的结果,使用while循环。谢谢你的帮助。
一般来说,在R中不推荐这种在循环中增长向量的方法。参见第2圈:帕特里克·伯恩斯的R地狱的成长对象。此外,R有许多紧凑的语句,如apply系列,以避免在初始化空对象并展开它时进行簿记。此外,R在其范式中更倾向于功能化和面向对象。如果可能的话,在一个对象上运行整个进程,比如向量化操作,避免基于状态/实例的数据处理。
具体来说,您当前的问题是,在每个循环迭代中,您继续添加all新颖的BookID
s到NovelID
向量,不需要用迭代器x
逐个条件。
循环中的生长对象
NovelID <- NULL
x <- 1
while(x <= 25) {
if(length(NovelID) <= 25) {
NovelID <- c(NovelID, SalesList$BookID[SalesList$BookType == "Novel"][x])
x <- x + 1
}
}
使用预定义长度
但最好用长度初始化对象,并通过索引赋值。
NovelID <- vector(mode="integer", length=25)
x <- 1
while(x <= 25) {
if(length(NovelID) <= 25) {
NovelID[x] <- SalesList$BookID[SalesList$BookType == "Novel"][x]
}
x <- x + 1
}
申请家庭
最好避免任何初始化对象的记录和重复赋值。
# VECTOR OUTPUT IF YOU DO NOT KNOW OUTPUT TYPE
NovelID <- sapply(1:25, function(x) SalesList$BookID[SalesList$BookType == "Novel"][x])
# VECTOR OUTPUT IF YOU DO KNOW OUTPUT TYPE
NovelID <- vapply(1:25, function(x) SalesList$BookID[SalesList$BookType == "Novel"][x], integer(1))
然而,你想避免任何循环(隐藏或不隐藏)与矢量化操作
NovelID <- SalesList$BookID[SalesList$BookType == "Novel"][1:25]
NovelID <- head(SalesList$BookID[SalesList$BookType == "Novel"], 25)
在线演示