2017-05-05 65 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

相關問題