以下是数据:
1:
30878
2647871
1283744
2488120
317050
1904905
1989766
14756
1027056
1149588
1394012
1406595
2529547
1682104
2625019
2603381
1774623
470861
712610
1772839
1059319
2380848
548064
10:
1952305
1531863
1000:
2326571
977808
1010534
1861759
79755
98259
1960212
97460
2623506
2409123
...
后跟':'的数字表示它是一个movieID,然后以下几行是customerID,我想写一个循环来检查数据是否包含':',这是我试过的代码:
for (i in 1:length(line)){
#print(line[i])
if(grep(':', line[i])==1 ){
movieID<-as.integer(substr(line[i],1,nchar(line[i])-1) )
next
}
else{
customerID<-as.integer(line[i])
#do something
}
}
当我运行此代码时,发生错误,错误是:参数的长度为零 我搜索了这个错误,然后我改变了if语句:
if( !is.na(line[i]) && nchar(line[i])>1 && grep(':', line[i])==1 )
仍然存在错误:缺少需要TRUE / FALSE的值
我无法解决它。 这是代码I:
for (i in 1:27){
#print(testData[i])
if(grep(':', testData[i])==1 ){
movieID<-as.integer(substr(testData[i],1,nchar(testData[i])-1) )
print(testData[i])
next
}else{
customerID<-as.integer(testData[i])
print(movieID)
print(customerID)
#print(subset.data.frame(mydata[[movieID]],mydata[[movieID]]$customerID==customerID) )
}
}
这是输出和错误:
[1] "1:"
Error in if (grep(":", testData[i]) == 1) { : argument is of length zero
看起来错误发生在else语句中。
答案 0 :(得分:1)
错误是因为如果您要查找的字符串不存在,grep
将返回logical(0)
。因此,您的循环在i=2
上失败,正如您在循环中断时查看i
的值时所看到的那样。
如果您使用grepl
代替,您的循环按计划运行(建立在@Akarsh Jain的答案上):
movieID<-array()
customerID<-array()
for (i in 1:length(testData)){
if(grepl(':', testData[i])){
movieID[i]<-as.integer(substr(testData[i],1,nchar(testData[i])-1) )
next
} else{
customerID[i]<-as.integer(testData[i])
}
}
当然,问题是这是多么有用。我假设你想以某种方式在movieID上分割你的数据,你可以使用dplyr
和tidyr
轻松地做到这一点:
library(dplyr)
library(tidyr)
#put your testData in a dataframe
testDf <- data.frame(customerID = testData)
newDf <- testDf %>%
#identify rows with :
mutate(movieID = ifelse(grepl(":",customerID), customerID, NA)) %>%
#fill all NA values in movieID with the previous non-NA value:
fill(movieID) %>%
#remove lines where customerID has a ":":
filter(!grepl(":",customerID))
输出:
customerID movieID
1 30878 1
2 2647871 1
3 1283744 1
虚假数据
testData <- read.table(text='1:
30878
2647871
1283744
2488120
317050
1904905
1989766
14756
1027056
1149588
1394012
1406595
2529547
1682104
2625019
2603381
1774623
470861
712610
1772839
1059319
2380848
548064
10:
1952305
1531863
1000:
2326571
977808
1010534
1861759
79755
98259
1960212
97460
2623506
2409123', stringsAsFactors=FALSE)[[1]]
答案 1 :(得分:0)
虽然线路名称没有效果,但从未使用&#34; line&#34;作为一个名字 object,因为它是R的stats包中的函数名称。
问题是您每次都要为对象分配一个新值&#34; movieID &#34;或&#34; customerID &#34;而不是他们的索引作为循环进度。
每次&#34; movieID&#34;和&#34; customerID&#34;被新值取代。
要为数组索引赋值,您必须首先在外部循环中创建一个空数组。
请更换&#34; line&#34;任何其他对象名称。
movieID<-array()
customerID<-array()
for (i in 1:length(line)){
#print(line[i])
if(grep(':', line[i])==1 ){
movieID[i]<-as.integer(substr(line[i],1,nchar(line[i])-1) )
next
}
else{
customerID[i]<-as.integer(line[i])
#do something
}
}
希望这可能有助于@cloudiyang:)