How to use apply over a vector?
First note that even the numbers in col2 are character since when combined with other elements which are character they get coerced to character.
str(a)
## 'data.frame': 6 obs. of 2 variables:
## $ col1: int 1 2 3 4 5 6
## $ col2: chr "a" "b" "1" "c" ...
1) grepl thus we should use character processing like this:
grepl("^\\d+$", a$col2)
## [1] FALSE FALSE TRUE FALSE TRUE TRUE
grepl
is alredy vectorized so we don't need an apply
or related function to iterate over the elements of col2
.
2) (s)apply These also work but seems unnecessarily involved given that grepl
alone works:
sapply(a$col2, grepl, pattern = "^\\d+$")
## a b 1 c 2 3
## FALSE FALSE TRUE FALSE TRUE TRUE
apply(array(a$col2), 1, grepl, pattern = "^\\d+$")
## [1] FALSE FALSE TRUE FALSE TRUE TRUE
3) type.convert Another approach is to use type.convert
which will convert to numeric if it can be represented as one. Then we can use is.numeric
.
sapply(a$col2, function(x) is.numeric(type.convert(x)))
## a b 1 c 2 3
## FALSE FALSE TRUE FALSE TRUE TRUE
Applying a simple function over a vector using vapply
Your function has a bug in it. Instead of
Fun = function(x) x[x<0]=0
You actually want:
correct_fun = function(x){
x[x<0]=0
return(x)
}
As is, your function is not returning anything at the moment. It modifies x
but doesn't return it so it just dies with the function. Executing correct_fun
on A
I get:
[1] 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10
Apply function over two vectors of different lengths, and return a matrix in R
Try this
library(stringr)
t(sapply(names,str_detect,pattern=slices))
You can also do this in base R using grepl
sapply(slices, grepl, names)
How do I apply this for loop over my character vector and output another vector?
The out
is not initialized in the function
concat <- function(vector,SID){
out <- character(length(vector))
decrement_append <- "&decrementQuotas=true"
SID_append <- "?surveyId="
for(i in 1:length(vector)){
out[i] <- paste0(v[i],SID_append,SID,decrement_append)
}
out
}
-testing
> concat(v, "SV_55tYjKDRKYTRNIh")
[1] "R_2wmKOSbPWHl4VtT2?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true" "R_2TtslLEVNeHs2r73?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true"
[3] "R_ZF79IJ60LaxxsuR4?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true" "R_3JJDUkrZ07eIwnh5?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true"
[5] "R_3JrWuv9fsLK6qNx6?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true"
paste/paste0
are vectorized. So, looping is not really needed
concat2 <- function(vector,SID){
decrement_append <- "&decrementQuotas=true"
SID_append <- "?surveyId="
paste0(v, SID_append,SID,decrement_append)
}
-testing
> concat2(v, "SV_55tYjKDRKYTRNIh")
[1] "R_2wmKOSbPWHl4VtT2?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true" "R_2TtslLEVNeHs2r73?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true"
[3] "R_ZF79IJ60LaxxsuR4?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true" "R_3JJDUkrZ07eIwnh5?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true"
[5] "R_3JrWuv9fsLK6qNx6?surveyId=SV_55tYjKDRKYTRNIh&decrementQuotas=true"
Clojure iteration over vector of functions
It helps to not think in "code being executed" , but in "expression trees being reduced". Expression trees are rewritten until the result appears. Symbols are replaced by "what they stand for" and functions are applied to their arguments when a "live function" appears in the first position of a list; as in (some-function a b c)
. This is done in top-down fashion from the top of the expression tree to the leaves, stopping when the quote
symbol is encountered.
In the example below, we unfortunately cannot mark what has already been reduced and what not as there is no support for coloring. Note that the order of reduction is not necessarily the one corresponding to what the compiled code issued by the Clojure compiler actually would do.
Starting with:
(defn stats
[numbers]
(map #(% numbers) [sum count avg]))
...we shall call stats
.
First difficulty is that stats
can be called with a collection as a single thing:
(stats [a0 a1 a2 ... an])
or it could be called with a series of values:
(stats a0 a1 a2 ... an)
Which is it? Unfortunately the expected calling style can only be found by looking at the function definition. In this case, the definition says
(defn stats [numbers] ...
which means stats
expects a single thing called numbers
. Thus we call it like this:
(stats [3 4 10])
Now reduction starts! The vector of numbers that is the argument is reduced to itself because every element of a vector is reduced and a number reduces to itself. The symbol stats
is reduced to the function declared earlier. The definition of stats
is actually:
(fn [numbers] (map #(% numbers) [sum count avg]))
...which is a bit hidden by the defn
shorthand. Thus
(stats [3 4 10])
becomes
((fn [numbers] (map #(% numbers) [sum count avg])) [3 4 10])
Next, reducing the fn
expression yields a live function of one argument. Let's mark the live function with a ★ and let's use mathematical arrow notation:
(★(numbers ➜ (map #(% numbers) [sum count avg])) [3 4 10])
The live function is on first position of the list, so a function call will follow. The function call consists in replacing the occurrence of numbers
by the argument [3 4 10]
in the live function's body and stripping the outer parentheses of the whol expression:
(map #(% [3 4 10]) [sum count avg])
Symbols map
, sum
, count
, avg
resolve to known, defined functions, where map
and count
come from the Clojure core library, and the rest has been defined earlier. Again, we mark them as live:
(★map #(% [3 4 10]) [★sum ★count ★avg]))
Again, the # %
notation is a shorthand for a function taking one argument and inserting it into the %
position, let's make this evident:
(★map (fn [x] (x [3 4 10])) [★sum ★count ★avg]))
Reducing the fn
expression yields a live function of one argument. Again, mark with ★ and let's use mathematical arrow notation:
(★map ★(x ➜ (x [3 4 10])) [★sum ★count ★avg]))
A live function ★map
is in head position and thus the whole expression is reduced according to the specification of map
: apply the first argument, a function, to every element of the 2nd argument, a collection. We can assume the collection is created first, and then the collection members are further evaluated, so:
[(★(x ➜ (x [3 4 10])) ★sum)
(★(x ➜ (x [3 4 10])) ★count)
(★(x ➜ (x [3 4 10])) ★avg)]
Every element of the collection can be further reduced as each has a live function of 1 argument in head position and one argument available. Thus in each case, x
is appropriately substituted:
[(★sum [3 4 10])
(★count [3 4 10])
(★avg [3 4 10])]
Every element of the collection can be further reduced as each has a live function of 1 argument in head position. The exercise continues:
[ ((fn [x] (reduce + x)) [3 4 10])
(★count [3 4 10])
((fn [x] (/ (sum x) (count x))) [3 4 10])]
then
[ (★(x ➜ (reduce + x)) [3 4 10])
3
(★(x ➜ (/ (sum x) (count x))) [3 4 10])]
then
[ (reduce + [3 4 10])
3
(/ ((fn [x] (reduce + x)) [3 4 10]) (count [3 4 10]))]
then
[ (★reduce ★+ [3 4 10])
3
(/ (*(x ➜ (reduce + x)) [3 4 10]) (count [3 4 10]))]
then
[ (★+ (★+ 3 4) 10)
3
(/ (reduce + [3 4 10]) (count [3 4 10]))]
then
[ (★+ 7 10)
3
(★/ (★reduce ★+ [3 4 10]) (★count [3 4 10]))]
then
[ 17
3
(★/ 17 3)]
finally
[ 17
3
17/3]
You can also use function juxt
. Try (doc juxt)
on the REPL:
clojure.core/juxt
([f] [f g] [f g h] [f g h & fs])
Takes a set of functions and returns a fn that is the juxtaposition
of those fns. The returned fn takes a variable number of args, and
returns a vector containing the result of applying each fn to the
args (left-to-right).
((juxt a b c) x) => [(a x) (b x) (c x)]
Let's try that!
(def sum #(reduce + %))
(def avg #(/ (sum %) (count %)))
((juxt sum count avg) [3 4 10])
;=> [17 3 17/3]
((juxt sum count avg) [80 1 44 13 6])
;=> [144 5 144/5]
And thus we can define stats
alternatively as
(defn stats [numbers] ((juxt sum count avg) numbers))
(stats [3 4 10])
;=> [17 3 17/3]
(stats [80 1 44 13 6])
;=> [144 5 144/5]
P.S.
Sometimes Clojure-code is hard to read because you don't know what "stuff" you are dealing with. There is no special syntactic marker for scalars, collections, or functions and indeed a collection can appear as a function, or a scalar can be a collection. Compare with Perl, which has notation $scalar
, @collection
, %hashmap
, function
but also $reference-to-stuff
and $$scalarly-dereferenced-stuff
and @$collectionly-dereferenced-stuff
and %$hashmapply-dereferenced-stuff
).
Apply many functions to one vector
Similar to @CathG's comment, but without get
:
v <- rnorm(10)
funs <- list(mean, median, sd)
sapply(funs, function(fun, x) fun(x), x = v)
Or with do.call
:
sapply(funs, do.call, args = list(v))
How do you apply a function to each element of a dataset vector, and then return that vector?
R is manipulating vectors so, if v
is a vector, you can directly pass your equation as follow:
v2 <- 1 - exp(-v*theta)
And it will be apply to each element of v and stored it in v2
object (which will also be a vector).
here an example:
v <- 1:10
theta = 5
> 1 - exp(-v*theta)
[1] 0.9932621 0.9999546 0.9999997 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000 1.0000000
Related Topics
R Create Function to Add Water Year Column
How to Write a Data-Frame with One Column a List to a File
R: I Have to Do Softmatch in String
Assigning and Removing Objects in a Loop: Eval(Parse(Paste(
Adding a Ranking Column to a Dataframe
Rmarkdown Table with Cells That Have Two Values
Data.Table Join and J-Expression Unexpected Behavior
How to Classify a Given Date/Time by the Season (E.G. Summer, Autumn)
Plotting Axis Labels with Greek Symbols from a Vector
Removing Duplicate Values Row-Wise in R
Edit Individual Ggplots in Ggally::Ggpairs: How to Have the Density Plot Not Filled in Ggpairs
How to Merge Multiple Data.Frames and Sum and Average Columns at the Same Time in R
How to Reverse the Order of a Dataframe in R
Running an R Script Using a Windows Shortcut
How to Make Shinyapp to Use Environmental Variables When Deployed on the Web