【问题标题】:R argument is of length zero when using names(vector) in IF statement在 IF 语句中使用名称(向量)时,R 参数的长度为零
【发布时间】:2020-11-12 21:04:54
【问题描述】:

我有一个这样的数据框和一个向量:

# sample data
IDd= c(seq(1,8))
BTD= c("A","B","AB","O","AB","AB","O","O")
fg= c(rep(0.0025, each=2),rep(0.00125, each=2),rep(0.0011, each=2),rep(0.0015, each=2))
data_D=data.frame(IDd,BTD,A=c(rep(0,5),1,1,1),B=c(rep(0,6),1,1),C=c(rep(1,7),0),D=rep(1,8),E=c(rep(0,5),rep(1,2),0),fg,stringsAsFactors=FALSE)

data_D
  IDd BTD A B C D E      fg
2   2   A 0 0 1 1 0 0.00250
4   4  AB 0 0 1 1 0 0.00125
5   5   B 0 0 1 1 0 0.00110
6   6   O 0 0 1 1 0 0.00110
7   7  AB 0 0 1 1 0 0.00150
8   8  AB 1 0 1 1 1 0.00150
1   1   O 1 1 0 1 0 0.00250
3   3   O 1 1 1 1 1 0.00125

# character vector 
Rvec=c(1,"A",0,0,0,0,1,0.0031)
names(Rvec)=c("Idr","BTR","A","B","C","D","E","fg")
Rvec
     Idr      BTR        A        B        C        D        E       fg 
     "1"      "A"      "0"      "0"      "0"      "0"      "1" "0.0031" 

每次我想检查我的向量或数据框的名称时都会出错。这是代码

check.names=function(Rvec,Data){ 
  Rvec=as.vector(Rvec)
  Data=as.data.frame(Data)
if(names(Data)[3:ncol(Data)] != names(Rvec)[3:length(Rvec)]) stop("Error")
if(names(Rvec)[2] != "BTR") {
  names(Rvec)[2] = "BTR" 
 }
}

check.names(Rvec= Rvec, Data=data_D)
# Error in if (names(Data)[3:ncol(Data)] != names(Rvec)[3:length(Rvec)])
 # stop("Error") : 
 # argument is of length zero

每当我在两个if 语句中使用names 时,我都会收到此错误。你知道是什么导致了这个问题吗? 我也看了"argument is of length zero" in if statementr if statement meet error: argument is of length zero,但仍然无法解决这个问题。奇怪的是,当我单独运行if 语句时,我没有收到任何错误,但是一旦在函数中,我就会收到错误消息。 谢谢你的帮助。

@DanY,我刚刚在您的答案中修改了all.equal 行,它现在正在工作

# first modified vector
 names(Rvec)[2]="btr"
 names(Rvec)[3]="k"
 Rvec
     Idr      btr        k        B        C        D        E       fg 
     "1"      "A"      "0"      "0"      "0"      "0"      "1" "0.0031" 

# second modified vector 
Rvec1
     Idr      btr        A        B        C        D        E       fg 
     "1"      "A"      "0"      "0"      "0"      "0"      "1" "0.0031" 
# modified function

check.names=function(Rvec,Data){
  if(!is.vector(Rvec)) stop("Rvec must be a vector")
  if(!is.data.frame(Data)) stop("Data must be a data.frame")
  dnames <- names(Data)[3:ncol(Data)]
  rnames <- names(Rvec)[3:length(Rvec)]
  if(!isTRUE(all.equal(dnames, rnames))) stop("Names don't match")
  if(names(Rvec)[2] != "BTR") {
    names(Rvec)[2] = "BTR" 
  }  
  
}

# test for first modified vector Rvec
check.names(Rvec= Rvec, Data=data_D)
# Error in check.names(Rvec = Rvec, Data = data_D) : Names don't match

# test for second modified vector Rvec1
a=check.names(Rvec= Rvec1, Data=data_D)
a
[1] "BTR"

【问题讨论】:

  • if(names(data)[3:ncol(data)] R 区分大小写 data != Data
  • 我更正了它,但仍然得到同样的错误,你知道为什么吗? @史蒂夫M

标签: r if-statement compiler-errors


【解决方案1】:

您的函数使用该行

Rvec = as.vector(Rvec)

as.vector() 的帮助文档指出“如果结果是原子的,则删除所有属性。”这意味着当您运行 as.vector() 时,元素名称将被删除。

一种解决方案不是强制 Rvec 成为一个向量,而是检查它是一个向量。您还需要将第三行中的if() 语句更改为ifelse()all.equal()。这是具有这两个修复的一种解决方案(将 ... 替换为您的其余代码):

check.names <- function(Rvec,Data){ 
    if(!is.vector(Rvec)) stop("Rvec must be a vector")
    if(!is.data.frame(Data)) stop("Data must be a data.frame")
    
    dnames <- names(Data)[3:ncol(Data)]
    rnames <- names(Rvec)[3:length(Rvec)]
    
    if(!all.equal(dnames, rnames)) stop("Names don't match")
    ...
}

【讨论】:

  • 现在@DanY 我收到消息:the condition has length &gt; 1 and only the first element will be used(当我删除函数中的前两行并将其替换为您的 if cheks 时)??
  • OMG @DanY 现在我在添加 if(!all.equal(dnames==rnames)) stop("Names don't match") 时收到不同的错误消息 Error in all.equal.default(dnames == rnames) : argument "current" is missing, with no default 。我不明白我没有任何参数叫current
  • 当然,我从你那里学到了很多东西!我非常感谢您的耐心@DanY!它似乎有效,我现在将用不同的向量测试它!
  • 它现在可以工作了@DanY,我刚刚将!all.equal(dnames, rnames) 更改为isTrue(all.equal(dnames, rnames))
  • 感谢@DanY 的帮助,非常感谢!
猜你喜欢
  • 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
相关资源
最近更新 更多