Can lists be created that name themselves based on input object names?
Coincidentally, I just wrote this function. It looks a lot like @joran's solution, but it tries not to stomp on already-named arguments.
namedList <- function(...) {
L <- list(...)
snm <- sapply(substitute(list(...)),deparse)[-1]
if (is.null(nm <- names(L))) nm <- snm
if (any(nonames <- nm=="")) nm[nonames] <- snm[nonames]
setNames(L,nm)
}
## TESTING:
a <- b <- c <- 1
namedList(a,b,c)
namedList(a,b,d=c)
namedList(e=a,f=b,d=c)
Copied from comments: if you want something from a CRAN package, you can use Hmisc::llist
:
Hmisc::llist(a, b, c, d=a, labels = FALSE)
The only apparent difference is that the individual vectors also have names in this case.
Creating unique object names for list entries
Maybe there is a more elegant way but just going through the list and renaming items while keeping count of each name's uses works fine:
# all used names
names.used <- unique(unlist(sapply(listoflists, names)))
# usage counter for each name
names.n <- setNames(rep(0, length(names.used)), names.used)
for (i in seq_along(listoflists)) {
for (j in seq_along(listoflists[[i]])) {
name.ij <- names(listoflists[[i]])[j]
# rename second and further occurrences
if (names.n[name.ij] > 0) {
names(listoflists[[i]])[j] <- paste0(name.ij, names.n[name.ij])
}
# update counter
names.n[name.ij] <- names.n[name.ij] + 1
}
}
# [[1]]
# [[1]]$a
# [1] "1" "a" "3" "4"
#
# [[1]]$b
# [1] "5" "b" "6" "7"
#
#
# [[2]]
# [[2]]$a1
# [1] "1" "a" "2" "6"
#
# [[2]]$b1
# [1] "5" "b" "0" "8"
#
#
# [[3]]
# [[3]]$d
# [1] "1" "a" "2" "6"
#
# [[3]]$b2
# [1] "5" "b" "0" "8"
#
#
# [[4]]
# [[4]]$d1
# [1] "1" "a" "2" "3"
#
# [[4]]$b3
# [1] "5" "b" "0" "8"
#
# [[4]]$a2
# [1] "5" "b" "0" "8"
#
#
# [[5]]
# [[5]]$d2
# [1] "1" "a" "1" "1"
Why do we have to type the class name twice when instantiating a new object in Java?
On the left hand:
ClassName instancename
The ClassName
is declaring type (= class) of variable instancename
.
On the right hand:
new ClassName();
The ClassName()
is invoking a (constructor) method named ClassName()
.
So, you are doing two things at once.
ClassName instancename; // declaring type
instancename = new ClassName(); // invoking method
Your example:
ClassName instancename = new ClassName();
is just shortened style of the two instructions.
There are other styles of getting an instance of a class -- newInstance()
or getInstance()
for example.
That is: declaration of type and method of instantiation are the separate things. They are needed for their own purposes.
Give name to list variable
Since @akrun doesn't need any more points, here is an example showing how you can assign names to a list:
lst <- list(a="one", b="two", c=c(1:3))
names(lst)
[1] "a" "b" "c"
names(lst) <- c("x", "y", "z")
> lst
$x
[1] "one"
$y
[1] "two"
$z
[1] 1 2 3
Return a named list with various elements from function call
mget Use
mget
as shown below. To return all variables usemget(ls())
or to return all variables exceptx
usemget(setdiff(ls(), "x"))
.ls
will not return object names that begin with a dot unless theall
argument is used, i.e.ls(all = TRUE)
, which could be used to prevent certain variables from being returned. Another possibility is to use themode=
argument ofmget
to restrict the objects returned to ones that arenumeric
, say. See?mget
. Yet another approach to restrict the objects returned is to useFilter
on the result ofmget
. For example,res <- Filter(is.data.frame, mget(ls()))
only returns data frames.myfunc <- function(x){
a1 = 1
a2 = c(2,4)
a3 = data.frame(x = 1:10)
an = 'str'
res = mget(ls(pattern = "^a"))
return(res)
}
myfunc(3) # testenvironment Another possibility is to return the environment within the executing function. All objects in the function (not just the ones beginning with
a
) will be in the environment.myfunc2 <- function(x) {
a1 = 1
a2 = c(2,4)
a3 = data.frame(x = 1:10)
an = 'str'
res = environment()
return(res)
}
out <- myfunc2(3) # test
out$awithin Another possibility is to use
within
. Only variables created in the within will be returned.x
is used in thewithin
but not created in thewithin
so it is not returned.myfunc3 <- function(x) {
res <- within(list(), {
a1 <- x
a2 <- BOD
})
return(res)
}
myfunc3(3) # testMultiple ls Perform an
ls()
before and after the section creating the variables to be output and thenmget
the difference.myfunc4 <- function(x) {
.excl <- ls()
a1 <- x
a2 <- BOD
res <- mget(setdiff(ls(), .excl))
return(res)
}
myfunc4(3) # test
From a list of objects, get a character vector of their names
Once you run
tests <- list(mean, varience, skewness, kurtosis)
those symbols are evaluated and discarded. If you look at
tests[[2]]
or something, you can see there really isn't an original reference to varience
, but rather the funcion that the symbol varience
pointed to is now stored in a list. (Things work a bit differently when passing parameters to functions thanks to the promises and the call stack but that's not what you're doing here). There is no lazy-evaluation for list()
after you've run it.
If you want to keep the names of the functions, it's probably best to work with a named list. You can make a helper function like
nlist <- function(...) { dots<-substitute(...()); setNames(list(...), sapply(dots, deparse))}
tests <- nlist(mean, var, skewness, kurtosis)
Now the values are preserved as names
names(tests)
# [1] "mean" "var" "skewness" "kurtosis"
Related Topics
How to Get Discrete Factor Levels to Be Treated as Continuous
R, Conditionally Remove Duplicate Rows
R Dynamically Build "List" in Data.Table (Or Ddply)
Installing Rcppeigen on Amazon Ec2
How to Use Write.Table() and Ddply, Together
Warning: Replacing Previous Import 'Head' When Loading 'Utils' in R
Assign Colors to a Range of Values
How to Transpose a Tibble() in R
How to Draw Half-Filled Points in R (Preferably Using Ggplot)
Generate Random Integers Between Two Values with a Given Probability Using R
R: Why Kable Doesn't Print Inside a for Loop