When trying to use a Proc with Tuple containing union types as an argument:
proc = ->(t : Tuple(Float64|Int32, Float64|Int32)){ t[0] + t[1] }
proc.call({1, 3})
I get this error:
type must be Tuple(Float64 | Int32, Float64 | Int32), not Tuple(Int32, Int32)
Isn't the tuple {1,3} already of that type? If not, how can I pass a tuple of that type?
Or are tuples containing union types not supported when using a Proc?
Unfortunately you have to explicitly cast it for now:
proc = ->(t : {Float64|Int32, Float64|Int32}){ t[0] + t[1] }
proc.call({1, 3}.as({Float64|Int32, Float64|Int32}))
You can tidy it up a little bit with an alias:
alias Point = {Float64|Int32, Float64|Int32}
proc = ->(t : Point){ t[0] + t[1] }
proc.call({1, 3}.as(Point))
Or maybe even create a dedicated value type:
record Point, x : Float64|Int32, y : Float64|Int32
proc = ->(t : Point){ t.x + t.y }
proc.call(Point.new(1, 3))
Related
For example, I want to cast nat to seq of char in VDM++.
In the code below, I want operation setValueOfX to return "X is {value of q}", if q is of type nat and q < 3.
class A1
instance variables
private x : nat := 0;
operations
public setValueOfX : nat ==> seq of char
setValueOfX(q) ==
(
if is_nat(q) and q < 3
then
(
x := q;
-- The following line doesn't work
-- return "X is " ^ q;
)
else
return "Invalid value! Value of x must be more than 0 and less than 3.";
);
end A1
I've tried using ^ but I got the following error:
Error[207] : Rhs of '^' is not a sequence type
act : nat
exp : ( seq1 of # | [] )
No, you can't implicitly convert values like that in VDM.
If you just want to see the result in a textural form, you could look at the IO library, which lets you "print" a mixture of types to the console. Alternatively, if you must return a string, you could specify a function that converts a nat to a decimal string, and the return "Result is" ^ nat2str(q).
I am new to Nim, and wrote this simple code for fun:
var x: int = 3
var y: int = 4
if true:
y = 7
else:
x = 7
proc hello(xx: int, yy: int, ): int =
return xx + yy
hello(x, y)
The code seems fine (I checked with the Nim manuals), but it gives this weird error:
c:\Users\Xilpex\Desktop\Nim_tests\testrig.nim(12, 6) Error: expression 'hello(x, y)' is of type 'int' and has to be discarded
Why am I getting this error? Is there something I can do to fix it?
You are getting an error because procs declared to return values are meant to use that value somewhere, so the compiler reminds you that you are forgetting the result of the call. If some times you want the result, and others you want to ignore it, instead of creating a temporal variable you can use the discard statement or declare the proc as {.discardable.}.
I just found out why I was getting that error... It was because the procedure returned a value, and I wasn't storing that value anywhere. Here is the working code:
var x: int = 3
var y: int = 4
if true:
y = 7
else:
x = 7
proc hello(xx: int, yy: int, ): int =
return xx + yy
var output = hello(x, y)
I am interested in using Rcpp to create a data frame with a variable number of columns. By that, I mean that the number of columns will be known only at runtime. Some of the columns will be standard, but others will be repeated n times where n is the number of features I am considering in a particular run.
I am aware that I can create a data frame as follows:
IntegerVector i1(3); i1[0]=4;i1[1]=2134;i1[2]=3453;
IntegerVector i2(3); i2[0]=4123;i2[1]=343;i2[2]=99123;
DataFrame df = DataFrame::create(Named("V1")=i1,Named("V2")=i2);
but in this case it is assumed that the number of columns is 2.
To simplify the explanation of what I need, assume that I would like pass a SEXP variable specifying the number of columns to create in the variable part. Something like:
RcppExport SEXP myFunc(SEXP n, SEXP <other stuff>)
IntegerVector i1(3); <compute i1>
IntegerVector i2(3); <compute i2>
for(int i=0;i<n;i++){compute vi}
DataFrame df = DataFrame::create(Named("Num")=i1,Named("ID")=i2,...,other columns v1 to vn);
where n is passed as an argument. The final data frame in R would look like
Num ID V1 ... Vn
1 2 5 'aasda'
...
(In reality, the column names will not be of the form "Vx", but they will be known at runtime.) In other words, I cannot use a static list of
Named()=...
since the number will change.
I have tried skipping the "Named()" part of the constructor and then naming the columns at the end, but the results are junk.
Can this be done?
If I understand your question correctly, it seems like it would be easiest to take advantage of the DataFrame constructor that takes a List as an argument (since the size of a List can be specified directly), and set the names of your columns via .attr("names") and a CharacterVector:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::DataFrame myFunc(int n, Rcpp::List lst,
Rcpp::CharacterVector Names = Rcpp::CharacterVector::create()) {
Rcpp::List tmp(n + 2);
tmp[0] = Rcpp::IntegerVector(3);
tmp[1] = Rcpp::IntegerVector(3);
Rcpp::CharacterVector lnames = Names.size() < lst.size() ?
lst.attr("names") : Names;
Rcpp::CharacterVector names(n + 2);
names[0] = "Num";
names[1] = "ID";
for (std::size_t i = 0; i < n; i++) {
// tmp[i + 2] = do_something(lst[i]);
tmp[i + 2] = lst[i];
if (std::string(lnames[i]).compare("") != 0) {
names[i + 2] = lnames[i];
} else {
names[i + 2] = "V" + std::to_string(i);
}
}
Rcpp::DataFrame result(tmp);
result.attr("names") = names;
return result;
}
There's a little extra going on there to allow the Names vector to be optional - e.g. if you just use a named list you can omit the third argument.
lst1 <- list(1L:3L, 1:3 + .25, letters[1:3])
##
> myFunc(length(lst1), lst1, c("V1", "V2", "V3"))
# Num ID V1 V2 V3
#1 0 0 1 1.25 a
#2 0 0 2 2.25 b
#3 0 0 3 3.25 c
lst2 <- list(
Column1 = 1L:3L,
Column2 = 1:3 + .25,
Column3 = letters[1:3],
Column4 = LETTERS[1:3])
##
> myFunc(length(lst2), lst2)
# Num ID Column1 Column2 Column3 Column4
#1 0 0 1 1.25 a A
#2 0 0 2 2.25 b B
#3 0 0 3 3.25 c C
Just be aware of the 20-length limit for this signature of the DataFrame constructor, as pointed out by #hrbrmstr.
It's an old question, but I think more people are struggling with this, like me. Starting from the other answers here, I arrived at a solution that isn't limited by the 20 column limit of the DataFrame constructor:
// [[Rcpp::plugins(cpp11)]]
#include <Rcpp.h>
#include <string>
#include <iostream>
using namespace Rcpp;
// [[Rcpp::export]]
List variableColumnList(int numColumns=30) {
List retval;
for (int i=0; i<numColumns; i++) {
std::ostringstream colName;
colName << "V" << i+1;
retval.push_back( IntegerVector::create(100*i, 100*i + 1),colName.str());
}
return retval;
}
// [[Rcpp::export]]
DataFrame variableColumnListAsDF(int numColumns=30) {
Function asDF("as.data.frame");
return asDF(variableColumnList(numColumns));
}
// [[Rcpp::export]]
DataFrame variableColumnListAsTibble(int numColumns=30) {
Function asTibble("tbl_df");
return asTibble(variableColumnList(numColumns));
}
So build a C++ List first by pushing columns onto an empty List. (I generate the values and the column names on the fly here.) Then, either return that as an R list, or use one of two helper functions to convert them into a data.frame or tbl_df. One could do the latter from R, but I find this cleaner.
I'm trying to create a code to run a simple perceptron in SAS base.
I'd like to print in each iteration (or store in a table) the result and the target, but I get an error when I try to print y[i,]:
proc iml;
use percept; read all var{x1 X2} into X;
read all var{Y} into Y;
W={0,0}; b=0; k=0; L=nrow(X); eta=.8; o=0;
print w b k L eta;
do step = 1 to 6;
mistakes=0;
do i=1 to L;
o=(X[i, ]*W + b);
if Y[i, ]*o <= 0 then do;
W = W + eta*(Y[i, ]-o)*X[i,]`;
b = b + eta*(Y[i, ]-o)*1;
k=k+1; mistakes=mistakes+1;
print o Y[i, ] W b k mistakes;
end;
end;
end;
I get the error:
Syntax error, expecting one of the following: C, COLNAME, F, FORMAT,
L, LABEL, R,
ROWNAME, ], |). The option or parameter is not recognized and will be ignored.
Do I have any other form to print the target?
Thanks a lot!
Per the documentation on PRINT, you need to do it like this:
print(Y[i,])
This is because they overload the [ ] to indicate formatting, rownames/colnames, etc., which is rather silly (but presumably to imitate some other language?). So you just need to wrap (Y[i,]) like so.
Here's a silly example.
proc iml;
use sashelp.class;
read all var{name,sex} into class;
read all var{height,weight,age} into classN;
y = mean(classN[,2]);
print class;
print (class[1:2,]);
print y (class[1:2,]);
quit;
I may be missing something obvious, but how do you calculate 'powers' in SAS?
Eg X squared, or Y cubed?
what I need is to have variable1 ^ variable2, but cannot find the syntax... (I am using SAS 9.1.3)
got it! there is no function.
you need to do:
variable1 ** variable2;
data t;
num = 5;
pow = 2;
res = num**pow;
run;
proc print data = t;
run;
Use the POWER function and, if necessary, the CONSTANT function.
nbr_squared = power(nbr, 2);
nbr_cubed = power(nbr, 3);
E_to_the_power_2 = power(constant('E'),2);