Get a consistent vector of list item names

A list without names returns NULL for its names:

> names(list(1,2,3)) NULL 

but add one named thing, and suddenly the names have a list length:

 > names(list(1,2,3,a=4)) [1] "" "" "" "a" 

because now it's a named list. I would like the function, according to rnames, to make any list in the list of names, for example:

 rnames(list(1,2,3)) == c("","","") identical(rnames(list()), character(0)) length(rnames(foo)) == length(foo) # for all foo 

and the following, which is the same name ():

 rnames(list(1,2,3,a=3)) == c("","","","a") rnames(list(a=1,b=1)) == c("a","b") 

My current hacker method is to add a named case to the list, get the names, and then disable it:

 rnames = function(l){names(c(monkey=1,l))[-1]} 

but is there a better / right way to do this?

+7
source share
3 answers

An approach that looks a little cleaner is to assign names to a list:

 x <- list(1,2,3) names(x) <- rep("", length(x)) names(x) [1] "" "" "" 

Including it in a function:

 rnames <- function(x){ if(is.null(names(x))) names(x) <- rep("", length(x)) return(x) } 

Test cases:

 x1 <- rnames(list(1,2,3)) x2 <- rnames(list(1,2,3,a=3)) x3 <- rnames(list(a=1,b=1)) names(x1) [1] "" "" "" names(x2) [1] "" "" "" "a" names(x3) [1] "a" "b" 
+4
source

The names are in the attribute named ... names:

 > lis2 <- list("a", "b") > attributes(lis2) NULL > if(is.null(names(lis2)) ) {names(lis2) <- vector(mode="character", length=length(lis2))} > lis2 [[1]] [1] "a" [[2]] [1] "b" > names(lis2) [1] "" "" > attributes(lis2) $names [1] "" "" 
+1
source

How about something like that?

 rnames <- function(x) { if(is.null(names(x))) character(length(x)) else names(x) } 

It handles cases of list() and without names; and he does nothing if there are already names.

+1
source

All Articles