Reputation: 225
I have a dataframe and a vector like this:
# 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"
Everytime i want to check names of my vector or dataframe i got an error. Here is the code
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
I keep getting this error whenever i used names
in both if
statement. Do you know what cause this problem?
I also took a look at "argument is of length zero" in if statement, r if statement meet error: argument is of length zero, but still can not resolve this issue. The weird thing is when i run the if
statement separately i do not get any errors but once within the function i get the error message.
Thank you for your help .
@DanY, i just modified the line all.equal
in your answer and it is working now
# 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"
Upvotes: 0
Views: 284
Reputation: 6073
Your function uses the line
Rvec = as.vector(Rvec)
The help documentation for as.vector()
states that "if the result is atomic, all attributes are removed." This means that element names are dropped when you run as.vector()
.
One solution is not to coerce Rvec to be a vector, but rather to check that it is a vector. You'll also need to change the if()
statement in your third line to either an ifelse()
or an all.equal()
. Here's one solution with those 2 fixes (replace the ... with the rest of your code):
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")
...
}
Upvotes: 2