I have a named list in R:
l = list(a=1, b=2)
I would like to use this list in Rcpp, and iterate over both the values and the names. Ideally, it could be something like (using C++11 formatting for the sake of concision):
void print_list (List l)
for (pair < String, int > &p: l)
cout << p.first << ": " << p.second;
Is there a way to do it (even using plain C++)?
Many of these use cases are in fact visible in the unit tests.
Here I am quoting from tinytest/cpp/Vector.cpp:
Get names:
// [[Rcpp::export]]
CharacterVector integer_names_get( IntegerVector y ){
return y.names() ;
}
Index by name
// [[Rcpp::export]]
int integer_names_indexing( IntegerVector y ){
return y["foo"] ;
}
That should be enough to get you the vector you aim to iterate over.
Related
I am new to coding and struggling with a section in my code. I am at the part where i want to remove duplicate int values from my vector.
my duplicated vector contains: 1 1 2 1 4
my goal is to get a deduplicated vector: 1, 2, 4.
This is what I have so far, It also needs to be a rather simple solution. No pointers and fancy stuff as I still need to study those in the future.
for(int i = 0; i < duplicatedVector.size(); i++) {
int temp = duplicatedVector.at(i);
int counter = 0;
if(temp == duplicatedVector.at(i)) {
counter++;
if(counter > 1) {
deduplicatedVector.push_back(temp);
}
}
}
Could anyone tell me what I do wrong ? I genuinly am trying to iterate through the vector and delete duplicated int, in the given order.
Your algorithm is not well-enough thought out.
Break it up:
for each element of the original vector:
is it in the result vector?
yes: do nothing
no: add it to the result vector
You have your (1) loop, but the (2) part is confused. The result vector is not the same as the original vector, and is not to be indexed the same.
To determine whether an element is in a vector, you need a loop. Loop through your result vector to see if the element is in it. If you find it, it is, so break the inner loop. If you do not, you don't.
You can tell whether or not you found a duplicate by the final value of your inner loop index (the index into the result vector). If it equals result.size() then no duplicate was found.
Clearer variable naming might help as well. You are calling your original/source vector duplicatedVector, and your result vector deduplicatedVector. Even hasDuplicates and noDuplicates would be easier to mentally parse.
You could use a set since it eliminates duplicates:
#include <bits/stdc++.h>
using namespace std;
int main () {
vector<int> vec = vector<int>();
vector<int> dedupl = vector<int>();
vec.push_back(2);
vec.push_back(4);
vec.push_back(2);
vec.push_back(7);
vec.push_back(34);
vec.push_back(34);
set<int> mySet = set<int>();
for (int i = 0; i < vec.size(); i++) {
mySet.insert(vec[i]);
}
for (int elem : mySet) {
dedupl.push_back(elem);
}
for (int elem : dedupl) {
cout << elem << " ";
}
}
I never have used C++ before so this may be a dumb question.
In R I use this function to read from a socket:
socket_bin_reader <- function(in_sock) {
string_read <- raw(0)
while((rd <- readBin(in_sock, what = "raw", n=1)) > 0) {
if (rd == 0xff) rd <- readBin(in_sock, what = "raw", n =1)
string_read <- c(string_read, rd)
}
return(string_read)
}
This functions does exactly what I need, but has the disadvantage that it takes a lot of time to read large quantities of data. Therefore I am looking for ways to use C++.
I found this example on how to read byte-by-byte from a file (cpp-byte-file-reading)
The body from my function will probably be based on this example. My guess is that it will look like:
// [[Rcpp::export]]
NumericVector socket_bin_reader_C(??? in_sock) {
NumericVector out = NumericVector::create(??);
ifstream infile(in_sock, ios::in | ios::binary);
while (rd = infile.read(char*) > 0) {
if (rd == 0xff) rd = infile.read(char*);
add rd to out;
}
}
But I have two questions:
In Rcpp you have to provide a class for each parameter. What is the class for a socketConnection?
I know that in C or C++ you have to allocate memory. How can I dynamically reallocate more memory for the return vector?
Ben
I have a list of Numeric Vector and I need a List of unique elements. I tried Rcpp:unique fonction. It works very well when apply to a Numeric Vector but not to List. This is the code and the error I got.
List h(List x){
return Rcpp::unique(x);
}
Error in dyn.load("/tmp/RtmpDdKvcH/sourceCpp-x86_64-pc-linux-gnu-1.0.0/sourcecpp_272635d5289/sourceCpp_10.so") :
unable to load shared object '/tmp/RtmpDdKvcH/sourceCpp-x86_64-pc-linux-gnu-1.0.0/sourcecpp_272635d5289/sourceCpp_10.so':
/tmp/RtmpDdKvcH/sourceCpp-x86_64-pc-linux-gnu-1.0.0/sourcecpp_272635d5289/sourceCpp_10.so: undefined symbol: _ZNK4Rcpp5sugar9IndexHashILi19EE8get_addrEP7SEXPREC
It is unclear what you are doing wrong, and it is an incomplete / irreproducible question.
But there is a unit test that does just what you do, and we can do it by hand too:
R> Rcpp::cppFunction("NumericVector uq(NumericVector x) { return Rcpp::unique(x); }")
R> uq(c(1.1, 2.2, 2.2, 3.3, 27))
[1] 27.0 1.1 3.3 2.2
R>
Even if there isn't a matching Rcpp sugar function, you can call R functions from within C++. Example:
#include <Rcpp.h>
using namespace Rcpp;
Rcpp::Environment base("package:base");
Function do_unique = base["unique"];
// [[Rcpp::export]]
List myfunc(List x) {
return do_unique(x);
}
Thank you for being interested to this issue.
As I notified that, my List contains only NumericVector. I propose this code that works very well and faster than unique function in R. However its efficiency decreases when the list is large. Maybe this can help someone. Moreover, someone can also optimise this code.
List uniqueList(List& x) {
int xsize = x.size();
List xunique(x);
int s = 1;
for(int i(1); i<xsize; ++i){
NumericVector xi = x[i];
int l = 0;
for(int j(0); j<s; ++j){
NumericVector xj = x[j];
int xisize = xi.size();
int xjsize = xj.size();
if(xisize != xjsize){
++l;
}
else{
if((sum(xi == xj) == xisize)){
goto notkeep;
}
else{
++l;
}
}
}
if(l == s){
xunique[s] = xi;
++s;
}
notkeep: 0;
}
return head(xunique, s);
}
/***R
x <- list(1,42, 1, 1:3, 42)
uniqueList(x)
[[1]]
[1] 1
[[2]]
[1] 42
[[3]]
[1] 1 2 3
microbenchmark::microbenchmark(uniqueList(x), unique(x))
Unit: microseconds
expr min lq mean median uq max neval
uniqueList(x) 2.382 2.633 3.05103 2.720 2.8995 29.307 100
unique(x) 2.864 3.110 3.50900 3.254 3.4145 24.039 100
But R function becomes faster when the List is large. I am sure that someone can optimise this code.
Is there a base function in Rcpp that:
Fills entirely by a single value if size of a vector is 1.
Fills the other vector completely if same length.
Fills with an NA value if neither Vector are the same length nor a vector is of size 1.
I've written the above criteria as a function below using a NumericVector as an example. If there isn't a base function in Rcpp that performs said operations there should be a way to template the function so that given any type of vector (e.g. numeric, character and so on) the above logic would be able to be executed.
// [[Rcpp::export]]
NumericVector cppvectorize(NumericVector x,NumericVector y) {
NumericVector y_out(y.size());
if(x.size() == 1) {
for(int i = 0; i < y_out.size(); i++) {
y_out[i] = x[0];
}
} else if(x.size() == y_out.size()) {
for(int i = 0; i < y_out.size(); i++) {
y_out[i] = x[i];
}
} else {
for(int i = 0; i < y_out.size(); i++) {
y_out[i] = NA_REAL;
}
}
return y_out;
}
Unfortunately, the closest you will come to such a function is one of the rep variants that Rcpp supports. However, none of the variants match the desired output. Therefore, the only option is to really implement a templated version of your desired function.
To create the templated function, we will first create a routing function that handles the dispatch of SEXP objects. The rationale behind the routing function is SEXP objects are able to be retrieved from and surfaced into R using Rcpp Attributes whereas a templated version is not. As a result, we need to specify the SEXTYPE (used as RTYPE) dispatches that are possible. The TYPEOF() macro retrieves the coded number. Using a switch statement, we can dispatch this number into the appropriate cases.
After dispatching, we arrive at the templated function. The templated function makes use of the base Vector class of Rcpp to simplify the data flow. From here, the notable novelty will be the use of ::traits::get_na<RTYPE>() to dynamically retrieve the appropriate NA value and fill it.
With the plan in place, let's look at the code:
#include <Rcpp.h>
using namespace Rcpp;
// ---- Templated Function
template <int RTYPE>
Vector<RTYPE> vec_helper(const Vector<RTYPE>& x, const Vector<RTYPE>& y) {
Vector<RTYPE> y_out(y.size());
if(x.size() == 1){
y_out.fill(x[0]);
} else if (x.size() == y.size()) {
y_out = x;
} else {
y_out.fill(::traits::get_na<RTYPE>());
}
return y_out;
}
// ---- Dispatch function
// [[Rcpp::export]]
SEXP cppvectorize(SEXP x, SEXP y) {
switch (TYPEOF(x)) {
case INTSXP: return vec_helper<INTSXP>(x, y);
case REALSXP: return vec_helper<REALSXP>(x, y);
case STRSXP: return vec_helper<STRSXP>(x, y);
default: Rcpp::stop("SEXP Type Not Supported.");
}
// Need to return a value even though this will never be triggered
// to quiet the compiler.
return R_NilValue;
}
Sample Tests
Here we conduct a few sample tests on each of the supported data
# Case 1: x == 1
x = 1:5
y = 2
cppvectorize(x, y)
## [1] NA
# Case 2: x == y
x = letters[1:5]
y = letters[6:10]
cppvectorize(x, y)
## [1] "a" "b" "c" "d" "e"
# Case 3: x != y && x > 1
x = 1.5
y = 2.5:6.5
cppvectorize(x, y)
## [1] 1.5 1.5 1.5 1.5 1.5
hi guys i would like u to help me in my assignment i had try to solve it but there are some of the things that making me :s i knw how to creat the name and id
string Name;
int Id;
bt wt does it mean a pointer to a dynamically allocated array of grades:s:s:S?
i jst knw how to declare a pointer like : double* Grades;
here is the assignment......
Create a Class StudentGrades with the following Data members:
Name : type String
Id: type integer
Grades: a pointer to a dynamically allocated array of Grades. Type is: pointer to double (* double)
It includes the following member functions:
A No-argument Constructor
A Constructor that takes two arguments : a String and an Integer and initializes the Name with the String and the ID with the Integer.
Set and get functions for Name, ID
A print function for Student information. It prints name, Id and the grades.
An overloaded Assignment operator of the Class Objects
A Copy Constructor of the Class Objects
Use the Syntax for the copy constructor and the overloaded assignment operator.
In another file create a C++ program that prompts the user for data to create four objects of the class StudentGrades. The first object (std1) has 5 grades, and the second (std2) has 6 grades and the third (std3) has 4 grades and fourth (std4) has no grades and data.
Then copy std2 into std4 and assign std1 to std3. Then print the details of the four objects
hey i solved my assignment bt iam trying to running it bt it doesn't work can any body please tell me where the problem is n the program
#include <iostream>
using namespace std;
class student_grades{
private:
string name,n;
int Id,i;
double* grades[];
public:
student_grades();
student_grades(sting, int);
student_grades(const student_grades&);
void set(string name,int Id){
cout << "enter the name and the ID";
cin >> n >> i;
n = name;
i = Id;
}
void get(){
return i;
return n;
}
void student_grades (student_grades&opr){
name = name.opr;
Id = Id.opr;
grades[] = grades[].opr;
}
void student_info(){
cout << "the name of the student is:" << name;
cout << "the id for the srudent is:" << Id;
grades = new double[];
cout << "the grades of the student is:" << grades[] << endl;
delete []grades;
}
};
student_grades::student_grades() {}
student_grades::student_grades(string name, int Id) {
name=" ";
Id=0;
}
student_grades::student_grades(const student_grades& copy) {
name=copy.name;
Id=copy.Id;
}
int main() {
student_grades std1;
std1.set();
cin >> std1.grades[5];
std1.get();
student_grades std2;
std2.set();
cin >> std2.grades[6];
std2.get();
student_grades std3;
std3.set();
cin >> std3.grades[4];
std3.get();
student_grades std4;
std4.set();
cin >> std4.grades[];
std4.get();
std1 = std3;
std2 = std4;
cout << std1 << std2 << std3 << std4;
return 0;
}
A dynamically allocated array is an array that isn't given a specific size until run time, unlike a fixed array declaration is at compile time. A declaration of a fixed array looks like:
int grades[500];
That array will allocate memory for 500 integers and stay that way unless you destroy it or resize it.
Creating a dynamically allocated array would look more like this:
int* grades = NULL; // A declaration in your StudentGrades class
int n = <get size from somewhere>; // Makes the size "dynamic"
grades = new int[n]; // This definition could be in your StudentGrades ctor,
// with n being a parameter.
Then you could continue by initializing all of the array elements to 0 or fill up your array with other values as needed. When you're done with the array, clean it up. This could be in your destructor:
delete [] grades;
grades = NULL;