Skip to content
Prev 15448 / 63424 Next

.Call - applying setAttrib(x, R_DimSymbol, s) to a matrix being an element of a list

Dear Simon,

 > you gave us only a fragment of your code, so I can only guess what 
the problem is:

 > What is imgSize? The behavior you describe seems as if you re-using 
the imgSize SEXP in all elements.
 > AFAIR in your case setAttrib doesn't copy the value, so you need to 
do so yourself (or alloc new dim array
 > for each element).

Sorry, it is always a tradeoff - either to explain or put a relatively 
large code, which also uses non-standard libraries making the code 
difficult to read. imgSize values are reset in between: see the full 
code below. The SEXP pointer imgSize stays in tact, that's true, but its 
values are changed (the problem is, they are always the last in the 
row). I.e. if I have 3 images 40x20, 200x100 and 150x75 I will get three 
matrices of 150x75, but if I omit setAtrib and return vectors I get 
vectors of different length.

Oleg

SEXP load2DImages(SEXP fileNames) {
    int nFiles = LENGTH(fileNames);
    std::cout << "Loading " << nFiles << " files..." << std::endl;
    // SEXP result = allocList(nFiles);
    SEXP result = allocVector(VECSXP, nFiles);
    PROTECT(result);
    SEXP imgSize = allocVector(INTSXP, 2);
    PROTECT(imgSize);
    TRGB2DImage::Pointer image;
    TRGB2DReader::Pointer reader = TRGB2DReader::New();
    TRGB2DImage::SizeType size;   
    TRGB2DImage::IndexType pixIndex;
    for (int i = 0; i < nFiles; i++) {
        try {
            char *filename = CHAR(asChar(VECTOR_ELT(fileNames, i)));
            std::cout << std::endl << "Loading image file " << filename 
<< "... ";
            reader->SetFileName(filename);
            reader->Update();
            image = reader->GetOutput();
        } catch(...) {
            std::cout << "failed!";
            continue;
        }
        std::cout << std::endl;
        size = image->GetLargestPossibleRegion().GetSize();
        INTEGER(imgSize)[0] = size[1];
        INTEGER(imgSize)[1] = size[0];
        std::cout << size[0] << " x " << size[1] << std::endl;
        SET_VECTOR_ELT(result, i, allocVector(INTSXP, size[0] * size[1]));
        SEXP element = VECTOR_ELT(result, i);
        for (int ix = 0; ix < size[0]; ix++) {
            pixIndex[0] = ix;
            for (int iy = 0; iy < size[1]; iy++) {
                pixIndex[1] = iy;
                INTEGER(element)[size[1] * ix + iy] = 
getIntRGBColour(image->GetPixel(pixIndex));
            }
        }
        setAttrib(element, R_DimSymbol, imgSize);
    }
    UNPROTECT(2);
    if (nFiles == 1)
        return VECTOR_ELT(result, 0);
    else
        return result;
}

Dr Oleg Sklyar
European Bioinformatics Institute
Wellcome Trust Genome Campus
Hinxton, Cambridge, CB10 1SD
England
phone/fax  +44(0)1223 49 4478/4468
e-mail osklyar@ebi.ac.uk
Simon Urbanek wrote: