Reputation: 5376
Imagine that I have the following list
> test <- list("a" = 1, "b" = 2)
Each element of the list has a name :
> names(test)
Now, I want to extract that name using lapply()
because I want to use it in a new function which will be called using lapply. I just don't know how to extract the name of each element.
I've tried using deparse()
and substitute()
but the outcome is weird :
> lapply(test, function(x) {deparse(substitute(x))})
$a
[1] "X[[i]]"
$b
[1] "X[[i]]"
Does anyone has a clue ?
I want to do something like this : I have a list which is like test :
> test <- list("a" = matrix(1, ncol = 3), "b" = matrix(2, ncol = 3))
I want to apply a function to that list which transform the data inside each element and give a specific name for each column :
make_df <- function(x) {
output <- data.frame(x)
names(output) <- c("items", "type", NAME_OF_X)
return(output)
}
lapply(test, make_df)
The expected output is :
> test
$a
[,1] [,2] [,3]
[1,] 1 1 1
attr(,"names")
[1] "index" "type" "a"
$b
[,1] [,2] [,3]
[1,] 2 2 2
attr(,"names")
[1] "index" "type" "b"
I don't know how I can get the name of the element to give a name to my third column.
Upvotes: 15
Views: 26988
Reputation: 3688
Here's a solution using purrr
. It seems to run faster than the solution by aaronwolden but slower than akrun's solution (if that's important):
library(purrr)
map2(test, names(test), function(vec, name) {
names(vec) <- c("index", "type", name)
return(vec)
})
$a
[,1] [,2] [,3]
[1,] 1 1 1
attr(,"names")
[1] "index" "type" "a"
$b
[,1] [,2] [,3]
[1,] 2 2 2
attr(,"names")
[1] "index" "type" "b"
Upvotes: 9
Reputation: 3753
Assuming you meant for both elements of test
to contain a 3-columned matrix, you can use mapply()
and provide separately the list and the list's names:
test <- list("a" = matrix(1, ncol = 3), "b" = matrix(2, ncol = 3))
make_df <- function(x, y) {
output <- data.frame(x)
names(output) <- c("items", "type", y)
return(output)
}
mapply(make_df, x = test, y = names(test), SIMPLIFY = FALSE)
which produces:
## $a
## items type a
## 1 1 1 1
##
## $b
## items type b
## 1 2 2 2
Update
To achieve the expected output you describe in your updated question:
test.names <- lapply(names(test), function(x) c("index", "type", x))
Map(setNames, test, test.names)
produces:
## $a
## [,1] [,2] [,3]
## [1,] 1 1 1
## attr(,"names")
## [1] "a" "index" "type"
##
## $b
## [,1] [,2] [,3]
## [1,] 2 2 2
## attr(,"names")
## [1] "b" "index" "type"
Upvotes: 7
Reputation: 887901
Based on the expected output showed
make_attr_names <- function(x){
x1 <- test[[x]]
attr(x1, 'names') <- c('items','type', x)
x1}
lapply(names(test), make_attr_names)
#[[1]]
# [,1] [,2] [,3]
#[1,] 1 1 1
#attr(,"names")
#[1] "items" "type" "a"
#[[2]]
# [,1] [,2] [,3]
#[1,] 2 2 2
#attr(,"names")
#[1] "items" "type" "b"
Or based on the description
make_df <- function(x){
setNames(as.data.frame(test[[x]]), c('items', 'type', x))}
lapply(names(test), make_df)
#[[1]]
# items type a
#1 1 1 1
#[[2]]
# items type b
#1 2 2 2
Upvotes: 3