【问题标题】:r if statement meet error: argument is of length zeror if 语句遇到错误:参数长度为零
【发布时间】:2017-05-05 05:14:14
【问题描述】:

这是数据:

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 的地方缺少值

我无法解决。 这是我的代码:

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 语句中。

【问题讨论】:

  • 您可以添加打印语句来尝试查看您的代码在哪一行失败了吗?逻辑对我来说是正确的(我在本地测试了每一块)。也许您的文件在某处有一些不良数据。也许是因为 EOF 案例而失败?
  • 我已经更新了问题,我确定数据是正确的。

标签: r if-statement


【解决方案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,您可以使用dplyrtidyr 轻松完成:

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

【讨论】:

    【解决方案2】:

    虽然行名不会生效,但千万不要使用“行”作为 对象,因为它是 R 的 stats 包中的函数名称。

    问题是您每次都为对象“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 :)

    【讨论】:

    • 很遗憾,我已经更改了对象名称并尝试添加movieID
    猜你喜欢
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多