在 IF 语句中使用名称(向量)时,R 参数的长度为零

R argument is of length zero when using names(vector) in IF statement

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

# 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 statement, ,还是没能解决这个问题。奇怪的是,当我 运行 和 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"

您的函数使用行

Rvec = as.vector(Rvec)

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

时,元素名称将被删除

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

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