2017-05-05 156 views
0

这里是数据:R如果语句满足错误:变量是长度为零

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需要

我解决不了。 这是我的代码:它看起来像发生在else语句错误

[1] "1:" 
Error in if (grep(":", testData[i]) == 1) { : argument is of length zero 

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)) 
    } 
} 

这里是放出来和错误。

+0

你能添加打印语句以尝试查看代码失败的哪一行?逻辑看起来对我来说是正确的(我在本地测试每一块)。也许你的文件有一些不好的数据。也许这是因为EOF情况而失败? –

+0

我有更新的问题,我敢肯定数据是正确的。 – cloudiyang

回答

1

错误是因为grep回报logical(0),如果你正在寻找的字符串不存在。因此,您的循环在i=2上失败,正如您在循环中断时查看i的值所见。

如果您在使用代替grepl,你的循环工作按计划(上@Akarsh耆那教的回答是建筑):

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]) 

    } 
} 

ofcourse,问题是这是多么有用的。我假设你想使用dplyrtidyr莫名其妙地劈在movieID,您可以轻松地做你的数据:

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]] 
+0

谢谢,这是正确的! – cloudiyang

+0

另请参阅编辑可能更快的解决方案 –

0

Although line name won't effect but never use "line" as a name of object because it is a name of function in stats package of R.

的问题是每次都分配一个新的值对象“movieID”或“的customerID”不以他们作为循环进度指标。

每次“movieID”和“customerID”被新值所取代。

要为数组索引赋值,您必须首先在外部循环中创建一个空数组。

请将“line”替换为任何其他对象名称。

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 :)

+0

很伤心,我已经更改了对象名称,并尝试添加movieID <-array() customerID <-array(),但它不起作用。 – cloudiyang