Reputation: 8494
I am applying a function onto a dataframe
.
But unlike sapply
and its friends, apply
hasn't got any USE.NAME
argument to get a named list as returned object.
In this example, I'd like the C
column to be the names of the returned list :
df = data.frame(A=c(1,2,3), B=c(9,5,7), C=c("A", "Z", "E"))
apply(df, 1, function(x){
data.frame(xxx=as.numeric(x[1]) * as.numeric(x[2]))
})
# [[1]]
# xxx
# 1 9
#
# [[2]]
# xxx
# 1 10
#
# [[3]]
# xxx
# 1 21
How can I achieve this ?
Upvotes: 2
Views: 554
Reputation: 4187
You don't need the apply
-function for this. You can just do:
setNames(as.list(df[[1]] * df[[2]]), df[[3]])
The result:
$A
[1] 9
$Z
[1] 10
$E
[1] 21
Upvotes: 0
Reputation: 887221
If the output should be the product of two columns in a list
, then it can be done with Reduce
lst <- as.list(Reduce(`*`, df[-3]))
names(lst) <- df[,3]
Or with tidyverse
library(tidyverse)
df %>%
transmute(xxx = A * B, C) %>%
split(.$C) %>%
map(~.x %>%
select(xxx))
Or with nest
df %>%
transmute(xxx = A * B, C) %>%
nest(xxx) %>%
mutate(data = set_names(data, C)) %>%
pull(data)
#$A
# xxx
#1 9
#$Z
# xxx
#2 10
#$E
# xxx
#3 21
Upvotes: 1
Reputation: 10671
or use setNames()
after you call apply:
setNames(apply(df, 1, function(x) {
data.frame(xxx=as.numeric(x[1]) * as.numeric(x[2]))
}), df$C)
Upvotes: 2
Reputation: 50678
You could do:
apply(data.frame(df, row.names = df$C), 1, function(x){
data.frame(xxx=as.numeric(x[1]) * as.numeric(x[2]))
})
#$A
# xxx
#1 9
#
#$Z
# xxx
#1 10
#
#$E
# xxx
#1 21
Explanation: apply
picks up list
names from the dimnames of your corresponding MARGIN
of your data.frame
(in your case MARGIN=1
, so list
names will correspond to rownames).
Upvotes: 3