Applying some functions to multiple objects
It is generally encouraged (by the R Core team memebers) that if you have several data sets that you want to simultaneously operate on, you should keep them all in a list. In order to achieve your goal, you can simply use mget
and ls
to retreive them from the global environment and then simply replace with first column multiplied by 2, e.g.,
lapply(mget(ls(pattern = "[a-z]")), function(x) x <- x[1] * 2)
# $a
# X1
# 1 2
# 2 4
# 3 6
# 4 8
# 5 10
#
# $b
# X1
# 1 22
# 2 24
# 3 26
# 4 28
# 5 30
Applying same function on multiple objects in R
Create a named list :
list_all<- dplyr::lst(list_csfiles,list_tsfiles,list_dmfiles,list_tmfiles)
In the function pass data and name seperately :
newey<-function(list_files, name) {
#All the code as it is
#...
#...
#...
write.xlsx(cs_nw_full, paste0(name, ".xlsx"))
}
You can then use Map
:
Map(newey, list_all, names(list_all))
Or with purrr::imap
purrr::imap(list_all, newey)
Apply a set of functions to an object
Some good answers already but throw in another option - build a pipe chain as a string then evaluate it. For example - for row 1 - eval(parse(text = "1 %>% rule1"))
gives 2
eval_chain <- function(df) {
eval(parse(text = paste(c(df$data, unlist(strsplit(df$rules, ", "))), collapse=" %>% ")))
}
df$value <- sapply(1:nrow(df), function(i) df[i, ] %>% eval_chain)
# data rules value
# 1 1 rule1 2
# 2 2 rule1, rule2, rule3 125
# 3 3 rule3, rule2 28
Sequentially apply multiple functions to object using different lenses
As well as OriDrori's converge
solution, you could also use either of two other Ramda functions. I always prefer lift
to converge
when it works; it feels more like standard FP, where converge
is very much a Ramda artifact. It doesn't always do the job because of some of the variadic features of converge
. But it does here, and you could write:
const calc = pipe (
over (arrLens, map (multiply (2))),
lift (set (res0sumOfDblLens) ) (
pipe (view (arrLens), sum),
identity
)
)
But that identity
in either of these solutions makes me wonder if there's something better. And there is. Ramda's chain
when applied to functions is what's sometimes known as the starling combinator, :: (a -> b -> c) -> (a -> b) -> a -> c
. Or said a different way, chain (f, g) //~> (x) => f (g (x)) (x)
. And that's just what we want to apply here. So with chain
, this is simplified further:
const arrLens = lensProp('arr')const res0sumOfDblLens = lensPath(['result', 'sumOfDoubled'])
const calc = pipe ( over (arrLens, map (multiply (2))), chain ( set (res0sumOfDblLens), pipe (view (arrLens), sum) ))
const obj = { arr: [2, 3], result: { sumOfDoubled: 0 }}
console .log (calc (obj))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script><script>const {lensProp, lensPath, pipe, over, map, multiply, chain, set, view, sum} = R </script>
Perform a single function on multiple object
While you've already accepted an answer, this is possible in a similar manner either natively through JavaScript 1.6/ECMAScript 5th Edition:
function logElementID(element, index, array) {
var el = array[index],
prop = el.textContent ? 'textContent' : 'innerText';
el[prop] = el.id;
}
[document.getElementById('one'), document.getElementById('two')].forEach(logElementID);
JS Fiddle demo.
Or by extending the Object
prototype:
function doStuff (el) {
console.log(el);
};
Object.prototype.actOnGroup = function(func){
var els = this.length ? this : [this];
for (var i = 0, len = els.length; i<len; i++){
func(els[i]);
}
return this;
};
document.getElementsByTagName('div').actOnGroup(doStuff);
document.getElementById('one').actOnGroup(doStuff);
JS Fiddle demo.
Or by, similarly, extending the Array
prototype:
function doStuff (el) {
console.log(el);
};
Array.prototype.actOnGroup = function(func){
var els = this.length ? this : [this];
for (var i = 0, len = els.length; i<len; i++){
func(els[i]);
}
return this;
};
[document.getElementById('one'), document.getElementById('two')].actOnGroup(doStuff);
JS Fiddle demo.
Incidentally, if you'd like to provide a forEach()
alternative to users without (relatively) up-to-date JavaScript implementations, the Mozilla Developer Network page for forEach()
offers the following as '[an] algorithm 100% true to the ECMA-262, 5th edition':
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.com/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function forEach(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError("this is null or not defined");
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0; // Hack to convert O.length to a UInt32
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if ({}.toString.call(callback) !== "[object Function]") {
throw new TypeError(callback + " is not a function");
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (thisArg) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (Object.prototype.hasOwnProperty.call(O, k)) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
Copied verbatim, from the reference (below) from the MDN forEach()
article; 01/04/2013, at 14:30.
References:
Array.forEach()
.
Passing multiple objects into a function via sapply() or lapply() while maintaining the functionality of substitute() inside the function
The usual way of handling something like this is to send the desired name to the function as well. In this case it may help to name the elements in your list with the desired names. Perhaps something like this:
f <- c('1', '2', '3')
d <- lapply(f, read.table)
names(d) <- f # optionally some other names
MyFunc <- function(dat, nam) {
plot(dat[1]~dat[2])
title(main=nam)
dat.new <- some.manipulations(dat)
write.csv(dat.new, file=paste(nam, ".csv", sep=""))
}
lapply(names(d), function(n) MyFunc(d[[n]], n))
Related Topics
Categorical Scatter Plot with Mean Segments Using Ggplot2 in R
How to Optimize the Following Code with Nested While-Loop? Multicore an Option
Calculate Using Dplyr, Percentage of Na's in Each Column
Flip Facet Label and X Axis with Ggplot2
How to Remove Nas with the Tidyr::Unite Function
Determine If Data Frame Is Empty
Adjusting the Width of Legend for Continuous Variable
Using Shorthand Character Classes Inside Character Classes in R Regex
Predicting Probabilities for Gbm with Caret Library
Read.Table Reads "T" as True and "F" as False, How to Avoid
Generating Non-Duplicate Combination Pairs in R
How to Write Special Characters in Rmarkdown Latex Documents
Difference Between [] and $ Operators for Subsetting
Drawing a Tangent to the Plot and Finding the X-Intercept Using R
Identify Consecutive Sequences Based on a Given Variable
Constructing a Named List Without Having to Type Each Object's Name Twice