How to use lapply or a family of the apply function for calling a function within a function in R?
To avoid confusion, it is better to have anonymous function call
lapply(z, function(x) hrat(x, drat))
How to use lapply with a function that requires a vector as an argument
lapply
takes a list
as its first argument and a function as its second. Optional arguments for the function can be added as additional arguments to lapply
.
By using match(c(1,3), k)
, you are calling match
on c(1, 3)
and your list k
. What you want to do is to pass a function to lapply
that will take a vector x
as argument and return match(c(1, 3), x)
. lapply
will then execute this function on each element of your list k
.
This is how you should use lapply
:
k <- list(c(2,0,2,1),c(3,0,2,0),c(0,1,2,0))
lapply(k, function(x) match(c(1,3), x))
# [[1]]
# [1] 4 NA
#
# [[2]]
# [1] NA 1
#
# [[3]]
# [1] 2 NA
lapply with $ function
For the first example, you can just do:
lapply(dflist, `$.data.frame`, "a")
For the second, use the slot()
accessor function
lapply(mylist, "slot", "tab")
I'm not sure why method dispatch doesn't work in the first case, but the Note
section of ?lapply
does address this very issue of its borked method dispatch for primitive functions like $
:
Note:
[...]
For historical reasons, the calls created by ‘lapply’ are
unevaluated, and code has been written (e.g., ‘bquote’) that
relies on this. This means that the recorded call is always of
the form ‘FUN(X[[i]], ...)’, with ‘i’ replaced by the current
(integer or double) index. This is not normally a problem, but it
can be if ‘FUN’ uses ‘sys.call’ or ‘match.call’ or if it is a
primitive function that makes use of the call. This means that it
is often safer to call primitive functions with a wrapper, so that
e.g. ‘lapply(ll, function(x) is.numeric(x))’ is required to ensure
that method dispatch for ‘is.numeric’ occurs correctly.
using lapply for a function on a matrix with columns as elements in R
Here are several ways. You do not need apply
because R is vectorized:
with(df, a*2+x+y-z)
# [1] 5 9 12 15
with(df, sumfunc(a,x,y,z))
# [1] 5 9 12 15
If you really want to use apply
):
apply(df, 1, function(x) sumfunc(x[1], x[2], x[3], x[4]))
# [1] 5 9 12 15
Applying a Function to a Data Frame : lapply vs traditional way
When working within a data.frame
you could use apply
instead of lapply
:
x <- seq(1, 10,0.1)
y <- seq(1, 10,0.1)
data_frame <- expand.grid(x,y)
head(data_frame)
some_function <- function(x,y) { return(x+y) }
data_frame$new_column <- apply(data_frame, 1, \(x) some_function(x["Var1"], x["Var2"]))
head(data_frame)
To apply a function to rows set MAR = 1
, to apply a function to columns set MAR = 2
.
lapply
, as the name suggests, is a list-apply. As a data.frame
is a list of columns you can use it to compute over columns but within rectangular data, apply
is often the easiest.
If some_function
is written for that specific purpose, it can be written to accept a single row of the data.frame as in
x <- seq(1, 10,0.1)
y <- seq(1, 10,0.1)
data_frame <- expand.grid(x,y)
head(data_frame)
some_function <- function(row) { return(row[1]+row[2]) }
data_frame$yet_another <- apply(data_frame, 1, some_function)
head(data_frame)
Final comment: Often functions written for only a pair of values come out as perfectly vectorized. Probably the best way to call some_function
is without any function of the apply
-familiy as in
some_function <- function(x,y) { return(x + y) }
data_frame$last_one <- some_function(data_frame$Var1, data_frame$Var2)
Why does this lapply() function applied to a dataframe not produce the same results as its for-loop equivalent?
To make your lapply code work just replace <-
with <<-
:
DF_1[row, column] <<- DF_1[row, column] + val
Please see ?assignOps
for more info.
However, again I wouldn't recommend lapply
in this case (<<-
should be avoided in general)
Here is a data.table
approach:
library(data.table)
DT <- setDT(data.frame(
ID = c(1,1,1,2,2,2,3,3,3),
Period = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
Values = c(5, 10, 15, 50, 2, 4, 3, 6, 9),
Flags = c("X1","X0","X2","X0","X2","X0", "X2","X1","X1")
))
unique_flags <- unique(DT$Flags)
all_flags <- setDT(expand.grid(list(first_flag = unique_flags, last_flag = unique_flags)))
resultDT <- dcast(
data = DT[, .(first_flag = first(Flags), last_flag = last(Flags), first_value = first(Values)), by = ID][
all_flags, on = c("first_flag", "last_flag")],
last_flag ~ first_flag,
fun.aggregate = sum,
value.var = "first_value"
)
for (col_i in seq_len(ncol(resultDT))){
set(resultDT, which(is.na(resultDT[[col_i]])), col_i, 0)
}
print(resultDT)
Result:
last_flag X0 X1 X2
1: X0 50 0 0
2: X1 0 0 3
3: X2 0 5 0
# step by step ------------------------------------------------------------
library(data.table)
DT <- setDT(data.frame(
ID = c(1,1,1,2,2,2,3,3,3,4,4,4),
Period = c(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3),
Values = c(5, 10, 15, 50, 2, 4, 3, 6, 9, 3, 6, 9),
Flags = c("X1","X0","X2","X0","X2","X0", "X2","X1","X1", "X2","X1","X1")
))
unique_flags <- unique(DT$Flags)
all_flags <- setDT(expand.grid(list(first_flag = unique_flags, last_flag = unique_flags)))
resultDT <- DT[, .(first_flag = first(Flags), last_flag = last(Flags), first_value = first(Values)), by = ID] # find relevant flags
resultDT <- resultDT[all_flags, on = c("first_flag", "last_flag")] # merge all combinations
resultDT <- dcast(resultDT, last_flag ~ first_flag, fun.aggregate = sum, value.var = "first_value") # dcast
for (col_i in seq_len(ncol(resultDT))){
set(resultDT, which(is.na(resultDT[[col_i]])), col_i, 0)
}
print(resultDT)
trouble getting Lapply with on-the-fly function to run correctly
When you lapply through a data.frame, you are iterating through its columns, so you just apply something similar to what you have in apply, without the margin argument:
pros.dat = data.frame(matrix(rnorm(100*4),ncol=4),ind=rbinom(100,1,0.5))
lapply(pros.dat[,-5],function(i)t.test.by.ind(i,pros.dat[,5]))
Related Topics
Change Level of Multiple Factor Variables
How to Remove Rows with All Zeros Without Using Rowsums in R
Dplyr::Select One Column and Output as Vector
How to Convert Ensembl Id to Gene Symbol in R
Street Address to Geolocation Lat/Long
How to Append a Plot to an Existing PDF File
How to Assign Output of Cat to an Object
How to Calculate Wind Direction from U and V Wind Components in R
How to Combine Aes() and Aes_String() Options
Using If Else Conditions on Vectors
R: Expand and Fill Data Frame by Date in Series
How to Learn How to Write C Code to Speed Up Slow R Functions
Speeding Up Julia's Poorly Written R Examples
Predicting Lda Topics for New Data
Methods for Doing Heatmaps, Level/Contour Plots, and Hexagonal Binning
Using R and Plot.Ly - How to Script Saving My Output as a Webpage