2011-04-18 23 views
6

I matrisler R döndü anda C. Matris kontrol eden bir R, bir paket yazıyorum sıra/sütun adları için numaralarına sahiptir. Ben CR uzantısı, ayar matris sıra/sütun adları

Ben yaklaşık bir saat boyunca etrafında google'dan nesne değiştirirken yerine kendi satır/sütun adlarını atamak, ama henüz iyi bir çözüm bulamadık. En yakın bulduğum dimnames'tir, ama sadece iki boyutu değil, her bir sütunu adlandırmak istiyorum. Matrisler 4x4'ten büyük olsun, aşağıda yapmak istediklerimin sadece küçük bir örneğidir.

satır sayısı 4^x x satır adı yukarıda

Current 
    [,1] [,2] [,3] [,4] 
[1,] 0.20 0.00 0.00 0.80 
[2,] 0.25 0.25 0.25 0.25 
[3,] 0.25 0.25 0.25 0.25 
[4,] 1.00 0.00 0.00 0.00 
[5,] 0.20 0.00 0.00 0.80 
[6,] 0.25 0.25 0.25 0.25 
[7,] 0.25 0.25 0.25 0.25 
[8,] 1.00 0.00 0.00 0.00 
[9,] 0.20 0.00 0.00 0.80 
[10,] 0.25 0.25 0.25 0.25 
[11,] 0.25 0.25 0.25 0.25 
[12,] 1.00 0.00 0.00 0.00 
[13,] 0.20 0.00 0.00 0.80 
[14,] 0.25 0.25 0.25 0.25 
[15,] 0.25 0.25 0.25 0.25 
[16,] 1.00 0.00 0.00 0.00 

Desired 
    [A] [C] [G] [T] 
[AA] 0.20 0.00 0.00 0.80 
[AC] 0.25 0.25 0.25 0.25 
[AG] 0.25 0.25 0.25 0.25 
[AT] 1.00 0.00 0.00 0.00 
[CA] 0.20 0.00 0.00 0.80 
[CC] 0.25 0.25 0.25 0.25 
[CG] 0.25 0.25 0.25 0.25 
[CT] 1.00 0.00 0.00 0.00 
[GA] 0.20 0.00 0.00 0.80 
[GC] 0.25 0.25 0.25 0.25 
[GG] 0.25 0.25 0.25 0.25 
[GT] 1.00 0.00 0.00 0.00 
[TA] 0.20 0.00 0.00 0.80 
[TC] 0.25 0.25 0.25 0.25 
[TG] 0.25 0.25 0.25 0.25 
[TT] 1.00 0.00 0.00 0.00 
+0

dimnames her satır ve sütun, yüzeysel bir isim yapar dimnames dimnames (mat) mdsumner

cevap

3

Jim söylediği gibi, bu şimdiye nam aracılığı C fonksiyonu içine isimlerini geçiyorum R. yapmak çok daha kolaydır argüman.

#include <Rinternals.h> 
SEXP myMat(SEXP nam) { 
    /*PrintValue(nam);*/ 
    SEXP ans, dimnames; 
    PROTECT(ans = allocMatrix(REALSXP, length(nam), length(nam))); 
    PROTECT(dimnames = allocVector(VECSXP, 2)); 
    SET_VECTOR_ELT(dimnames, 0, nam); 
    SET_VECTOR_ELT(dimnames, 1, nam); 
    setAttrib(ans, R_DimNamesSymbol, dimnames); 
    UNPROTECT(2); 
    return(ans); 
} 

Eğer myMat.c adlı bir dosyada bu kodu koyarsanız, aşağıdaki hattı üzerinden test edebilirsiniz. Ben Ubuntu kullanıyorum, bu yüzden Windows üzerinde iseniz myMat.dll için myMat.so değiştirmek zorunda kalacaktır.

R CMD SHLIB myMat.c 
Rscript -e 'dyn.load("myMat.so"); .Call("myMat", c("A","C","G","T"))' 
+0

Hmm, sorun, dizeleri SEXP nesnelerine alıyor. KORUMA (colnames = allocVector (VECSXP, 4)); \t KORUMA (A = NEW_CHARACTER (1)); SET_STRING_ELT (A, 0, mkChar ("A")); SET_VECTOR_ELT (rownames, 0, A); SET_VECTOR_ELT (rownames, 1, A); SET_VECTOR_ELT (rownames, 2, A); SET_VECTOR_ELT (rownames, 3, A); – Nick

+0

"myMat.so" ifadesini "myMat.dll" ile değiştirmek mi istiyorsunuz? Şu anda, okur biçimi "myMat.c" ifadesini "myMat.dll" olarak değiştireceğiniz gibi görünüyor. –

+0

@Gavin: Haklısınız; düzenlendi. –

1

not uzunluğudur öğretici olmasıdır. Dimnames, her bir öğenin bu boyuttaki sayı öğelerine, yani list(c('a','c','g','t'), c('a','c','g','t')) karşılık geldiği, veri kümesinin boyutları ile aynı sayıda öğeye sahip bir listedir.

C olduğunu belirlemek için, ben tavsiye ederim:

PROTECT(dimnames = allocVector(VECSXP, 2)); 
PROTECT(rownames = allocVector(STRSXP, 4)); 
PROTECT(colnames = allocVector(STRSXP, 4)); 
setAttrib(? , R_DimNamesSymbol, dimnames); 

Ardından ilgili rowname ve colname unsurları ayarlamak gerekir. Genel olarak, bu şeyler

jim R. yapmak daha kolay çok

+0

colnames. @Nick: Ben de bunu R. –

+0

Jim'de yapmamanızı tavsiye ederim, ayrıca KORUNMALI (4) olması gerekir. Denedim ve işe yaramadı. Yine de – Nick

+0

denemeye devam edeceğim En azından aşağıdakilere ihtiyacınız var, ama hala çalışmıyor ...SET_STRING_ELT (rownames, 0, mkChar ("A")); SET_VECTOR_ELT (dimnames, 0, rownames); SET_VECTOR_ELT (dimnames, 1, colnames); – Nick

6

Eğer C açıksa ++ yerine C, daha sonra Rcpp bu biraz kolaylaştırabilir. Biz sadece satır ve sütun adlarını içeren bir liste nesnesi biz Ar yaptığınız gibi oluşturun ve matris nesnesinin dimnames özniteliği bu atayın:

R> library(inline)       # to compile, link, load the code here 
R> src <- ' 
+ Rcpp::NumericMatrix x(2,2); 
+ x.fill(42);       // or more interesting values 
+ // C++0x can assign a set of values to a vector, but we use older standard 
+ Rcpp::CharacterVector rows(2); rows[0] = "aa"; rows[1] = "bb"; 
+ Rcpp::CharacterVector cols(2); cols[0] = "AA"; cols[1] = "BB"; 
+ // now create an object "dimnms" as a list with rows and cols 
+ Rcpp::List dimnms = Rcpp::List::create(rows, cols); 
+ // and assign it 
+ x.attr("dimnames") = dimnms; 
+ return(x); 
+ ' 
R> fun <- cxxfunction(signature(), body=src, plugin="Rcpp") 
R> fun() 
    AA BB 
aa 42 42 
bb 42 42 
R> 

sütun ve satır isimlerinin gerçek atama böylece manuel olduğunu .. çünkü geçerli C++ standardı, başlatma sırasında vektörlerin doğrudan atanmasına izin vermez, ancak bu değişecektir.

Düzenleme: Sadece tabii satırda statik create() yöntemi kullanabilirsiniz fark ve çok colnames, bu biraz daha kolay ve daha kısa hale getirir hala

R> src <- ' 
+ Rcpp::NumericMatrix x(2,2); 
+ x.fill(42);       // or more interesting values 
+ Rcpp::List dimnms =     // two vec. with static names 
+  Rcpp::List::create(Rcpp::CharacterVector::create("cc", "dd"), 
+       Rcpp::CharacterVector::create("ee", "ff")); 
+ // and assign it 
+ x.attr("dimnames") = dimnms; 
+ return(x); 
+ ' 
R> fun <- cxxfunction(signature(), body=src, plugin="Rcpp") 
R> fun() 
    ee ff 
cc 42 42 
dd 42 42 
R> 

yüzden aşağı üç veya üzeresiniz dört ifade, PROTECT/UNPROTECT ile hiçbir maymun ve hiçbir bellek yönetimi.

+0

Öneriniz için teşekkürler, ancak maalesef C ile sınırlıyım. – Nick

+0

Gerçekten de gcc ile C'ye sahip olan her R yüklemesi de g ++ ile C++ içeriyor ve nesne kodu birlikte çalışıyor. –

+0

".attr (" rownames ")', '.attr (" colnames ")', '.attr (" names ")' da olduğu gibi, sadece sütun veya satır adlarını belirtmek istendiğinde? Bu bilgileri dokümanlarda nerede bulabiliriz? – highBandWidth