How can I use characters in a function as argument in R? - r

I want to update a date file which I want to assign weight to a name.
For example :
weight_f = function(Name = 0, Weight = 0){
data$Weight = ifelse(data$Name==Name, Weight, NA)
}
The problem is that I need to have Name as "Name" after ==. I tried pasting " before and after, but it wont work because R wont let me enter """

Very easy fix :)
weight_f = function(Name = 0, Weight = 0){
data$Weight = ifelse(data$Name==deparse(substitute(Name)), Weight, NA)
}
Edit:
Actually, I think I misunderstood what you were asking, and my answer doesn't make any sense because of it (in the case I thought you meant, you would have just used "Name" rather than deparse(substitute(Name)) - same output).
I think probably what you want is toString :
weight_f = function(Name = 0, Weight = 0){
data$Weight = ifelse(data$Name==toString(Name), Weight, NA)
}

Related

if and else with vector sum condition not properly working

I have a data.frame called sites_sp where I'm trying to run some functions based on if and else statements. sites_sp has the following structure:
structure(list(x = c(-50.1298257841559, -49.9523708108406, -49.8600298829818,
-49.8590735594872, -49.8600022102151, -49.680556540172), y = c(-29.2498490060132,
-29.1594734717135, -29.0700140387022, -28.9795033961473, -28.8900003372153,
-28.8945716273705), ua = c("ua_1", "ua_4", "ua_10", "ua_15",
"ua_21", "ua_23"), occ = c(0, 0, 0, 0, 0, 0), PC1 = c(0.403336553595704,
-0.209623013249306, -2.38969068562858, -1.0875631345167, 0.0424075103800285,
-1.69180948954307), PC2 = c(-3.62346919232857, -4.03856503375702,
-1.46862258765078, -1.77908267718137, -2.0250031837701, -0.952927464794925
), PC3 = c(-0.375601733371977, -0.122982261539736, -0.365818414058142,
-0.111150398019996, 0.287459840686463, 0.034973266100254), PC4 = c(-1.31153262462204,
-0.899941801783298, -1.35652371929479, -1.98693913441246, -1.75393016363327,
-0.788097574287776), PC5 = c(1.42830395246321, 1.55155187773266,
1.33933059031444, 0.0760013457702872, 0.588191290690648, -0.408003273953271
)), row.names = c(NA, 6L), class = "data.frame")
What I'm doing is an if and else statements of form:
for(s in sp){
if(sum(sites_sp$occ >= 30)){
pa_data <- st_as_sf(sites_sp,
coords = c("x", "y"),
crs = crs(env_terra))
...
} else {
block of functions for the statement being FALSE
}
}
RELEVANT EDIT: From what I can tell, the function is going directly to the else block even though it should not — since sum(sites_sp$occ) is bigger than 30 for the first s in sp
I can't really understand what's going on. If I try sum(sites_sp$occ) it returns for me a value of 37, implying that the function inside the if block (pa_data <- st_as_sf()...) should run normally. What am I doing wrong here? If more information is needed, please tell me.
Ok, guys...I'm kinda dumb.
The problem is simply here:
if(sum(sites_sp$occ >= 30)){
Should be written as
if(sum(sites_sp$occ) >= 30){
My condition was inside the sum

PowerBI - Count Blank Values of specific Columns

My table looks a little like this. The last column is what I'm trying to figure out how to calculate. I can easily do this in Excel - but not sure how to write my formula in PowerBI
I don't think you can count it without specifying the individual columns. if that is what you are looking for. I would do it something like this:
Data Missing =
COUNTBLANK([Project Title])
+ COUNTBLANK([Status])
+ COUNTBLANK([Object])
There may be a more clever way to do this, but a simple DAX expression can do the job.
CountBlanksInRow =
VAR data1blank = IF (ISBLANK(Sheet1[Data 1]), 1, 0)
VAR data2blank = IF (ISBLANK(Sheet1[Data 2]), 1, 0)
VAR data3blank = IF (ISBLANK(Sheet1[Data 3]), 1, 0)
RETURN data1blank + data2blank + data3blank
Rather then using DAX or Measure, The best option is you can create the custom column in Power Query and the code will be as below-
Number.From([Project Title] = null)
+ Number.From([Status] = null)
+ Number.From([Objective] = null)
Here below is the sample code window-

Setting default of one function as default of another function

I want to understand if setting a function as the default to another function has caused anyone issues? Is this clearly not best practice?
add_this <- function(a = 1, b = 2){
a + b
}
print_what_we_added <- function(the_sum = add_this()){
paste0("the sum of what we added is ", the_sum)
}
print_what_we_added()
print_what_we_added(5)

R - Arrays with variable dimension

I have a weird question..
Essentially, I have a function which takes a data frame of dimension Nx(2k) and transforms it into an array of dimension Nx2xk. I then further use that array in various locations in the function.
My issue is this, when k == 2, I'm left with a matrix of degree Nx2, and even worse, if N = 1, I'm stuck with a matrix of degree 1x2.
I would like to write myArray[thisRow,,] to select that slice of the array, but this falls short for the N = 1, k = 2 case. I tried myArray[thisRow,,,drop = FALSE] but that gives an 'incorrect number of dimensions' error. This same issue arrises for the Nx2 case.
Is there a work around for this issue, or do I need to break my code into cases?
Sample Code Shown Below:
thisFunction <- function(myDF)
{
nGroups = NCOL(myDF)/2
afMyArray = myDF
if(nGroups > 1)
{
afMyArray = abind(lapply(1:nGroups, function(g){myDF[,2*(g-1) + 1:2]}),
along = 3)
}
sapply(1:NROW(myDF),
function(r)
{
thisSlice = afMyArray[r,,]
*some operation on thisSlice*
})
}
Thanks,
James

Cheapest way of doing max() on absolute values, but have max() preserve sign?

I have a 3-vector, let's say
v = vec3(-4, 2, 3)
I would like to do a max on the absolute values of the components, so the equivalent of:
max(abs(v[0]), max(abs(v[1]), abs(v[2]))) == 4
However, I have a requirement that I need to preserve the sign. So for example:
magic_max(v[0], magic_max(v[1], v[2])) == -4.
It's a trivial problem if I use conditional branching, but I'm trying to do this in as few operations as possible, and avoid branching. Any ideas on where to look? Maybe there's some bit-shifting magic that can be done?
I would determ the max AND the min of all values, and then decide what is abs larger
ma = max(v[0], max(v[1], v[2]));
mi = min(v[0], min(v[1], v[2]));
res = abs(mi) > ma ? mi : ma;
If you want to get the sign, replace the last line with an if
if (abs(mi) > ma) {
sign = -1;
res = mi;
} else {
sign = +1;
res = ma;
}
However, what should happen on (0, 0, 0)? no sign?

Resources