Reputation: 560
I want to apply a function to all columns of a dataframe. Within that function, I want to use the respective colnames. However, these are lost - how do I keep them, or otherwise refer to them within the function?
data <- data.frame("A" = rnorm(500, 0, 1),
"B" = rnorm(500, 0, 1))
funk <- function(x,...){
paste(colnames(x), " & ", round(mean(x, na.rm = T), 1), sep = "")
}
lapply(data, funk)
Gives:
$A
[1] " & -0.1"
$B
[1] " & 0.1"
But I want:
$A
[1] "A & -0.1"
$B
[1] "B & 0.1"
Upvotes: 0
Views: 209
Reputation: 99331
Since paste
is vectorized, you can use colMeans
with it and not have to loop anything.
paste(names(data), " & ", round(colMeans(data), 1))
So I'd probably write the function like this:
funk <- function(x, digits = 1L, na.rm = TRUE) {
means <- round(colMeans(x, na.rm = na.rm), digits = digits)
setNames(as.list(paste(names(x), " & ", means)), names(x))
}
funk(data)
# $A
# [1] "A & 0"
#
# $B
# [1] "B & 0"
funk(data, digits = 3)
# $A
# [1] "A & 0.023"
#
# $B
# [1] "B & -0.046"
But from your comment it seems like you might be wondering how to apply the names one-to-one while you're applying a function. For that you might want to look at Map
and/or mapply
Map(paste, names(data), " & ", round(colMeans(data), 3))
# $A
# [1] "A & 0.023"
#
# $B
# [1] "B & -0.046"
Upvotes: 2
Reputation: 24480
You don't need a lapply
if you use colMeans
instead of mean
:
funk <- function(x,...){
paste(colnames(x), " & ", round(colMeans(x, na.rm = T), 1), sep = "")
}
And then just:
funk(data)
Edit: the above will give you a simple character
vector as output. If you want a list
with names as per your desired output, just define funk
as follow:
funk <- function(x,...){
setNames(as.list(paste(colnames(x), " & ", round(colMeans(x, na.rm = T), 1), sep = "")),names(x))
}
Upvotes: 3
Reputation: 887118
You can try
lapply(seq_len(ncol(data)), function(i)
paste(colnames(data[i]), " & " , round(mean(data[,i],
na.rm=TRUE), 1), sep=""))
Upvotes: 1