Jest wiele ruchomych części w tym pytaniu. Kopanie poprzez dokumentację dla różnych części, myślę, że trzeba to zrobić na linii, który wybuchł:
gesinstance = .jnew("edu/cmu/tetrad/search/Ges", .jcast(dataset, "edu/cmu/tetrad/data/DataSet"))
Kluczową różnicą jest wywołanie .jcast
na drugim argumencie. (Nie mam zainstalowanej wersji R, więc nie mogłem tego przetestować - jeśli to nie zadziała, zaktualizuję moją odpowiedź na podstawie opinii, którą możesz przekazać w przypadku nowych komunikatów o błędach.)
A więc pytanie jest "Dlaczego to?" Odpowiedź wydaje się być:
- Po stronie Java
DataReader.parseTabularData
zwraca obiekt z typu DataSet
jak wspomniano, ale to nie DataSet
interfejs klasy. Oznacza to, że zwracany obiekt jest klasy, która implementuje interfejs DataSet
.
- Z powodów, które nie są dla mnie oczywiste, pakiet rJava nie radzi sobie dobrze z polimorfizmem. Wymaga to wywołania metod z "dokładnym" podpisem zgodnym z obiektami, które przekazujesz. W tym przypadku będziesz musiał "przerzucić" z jakiejś konkretnej klasy, którą masz do interfejsu
DataSet
. Zobacz dokumentację dla .jnew
(https://www.rforge.net/doc/packages/rJava/html/jnew.html), szczególnie dla argumentów, które oznaczają "...". Odwołuje się do odpowiedniej części dokumentacji dla .jcall
(https://www.rforge.net/doc/packages/rJava/html/jcall.html), po czym wyjaśnia objaśnienie wymagania wywołania .jcast
(https://www.rforge.net/doc/packages/rJava/html/jcast.html) z kilkoma przykładami.
Błąd, który otrzymałeś java.lang.NoSuchMethodError: <init>
, informował, że maszyna JVM nie może znaleźć konstruktora, który wywołałeś. To było tajemniczo wyglądające w przykładzie, który zamieściłeś w komentarzach. (Nawiasem mówiąc, dobrze byłoby edytować pytanie i umieścić tam informacje dla potomności.) Kod z pewnością wygląda dobrze i, znając Javę, intuicyjnie spodziewałem się, że interfejs będzie respektował polimorfizm Javy. Biorąc pod uwagę, że (z jakiegokolwiek powodu) interfejs do R dokonuje "dokładnego" dopasowywania typów bez uwzględniania dziedziczenia, jasne jest, że nie znajdzie konstruktora z powodu nr 1 powyżej.
Wreszcie, nie spotkałem się z żadnymi klasami Javy przy użyciu generycznych w mojej ograniczonej eksploracji Tetradu. Jak się okazało, był to jednak kompletny czerwony śledź. Jeśli będzie to problemem w przyszłości, prawdopodobnie będziesz chciał sprawdzić "Typ Erasure" (https://docs.oracle.com/javase/tutorial/java/generics/erasure.html). Jeśli łączyłeś się z Javą i C, C++, Fortranem, dowolnym językiem, który Java uważa za "natywny", radziłbyś sobie z rodzajami generycznymi w kodzie rodzimym, zajmując się typowymi formularzami. Interfejs rJava może być jednak inny, ponieważ wygląda na to, że wpadł on w ten sam ogólny typ struktury, który wyzwolił cię z obecnego problemu. (Być może godne własnej nagrody później!)
Jaka jest dokładna składnia, z której korzystasz podczas wywoływania '.jnew()'? Czy przekazujesz mu argumenty?Proszę dokładnie je określić. – Brick
Oto sprawdzony przykład. Musisz pobrać słoik Tetrad z [here] (http://www.phil.cmu.edu/projects/tetrad_download/download/tetrad-5.2.1-3.jar) (19mb) i przykładowy zestaw danych, charity.txt, from [here] (http://www.phil.cmu.edu/projects/tetrad_download/download/workshop/Data/charity.txt). Ustaw w R: 'setwd (" wherever/you/put/the/data/")', 'biblioteka (rJava)', '.jinit (" ścieżka/do/tetrad-5.2.1-3.jar ")'. Wszystkie poniższe prace: 1. 'filename = .jnew (" java/lang/String "," charity.txt ")', 2. 'datafile = .jnew (" java/io/File ", nazwa pliku)', 3. 'reader = .jnew (" edu/cmu/tetrad/data/DataReader ")', –
4. 'delim = J (" edu/cmu/tetrad/data/DelimiterType ")', 5. 'reader $ setDelimiter (delim $ TAB) ', 6.' dataset = reader $ parseTabular (plik danych) '. Ale nie działa: 7. 'gesinstance = .jnew (" edu/cmu/tetrad/search/Ges ", zbiór danych)'. czytnik $ parseTabular zwraca DataSet, a klasa Ges ma zostać utworzona za pomocą argumentu DataSet. Niestety to nie działa. Myślę, że powodem jest to, że Ges implementuje dwa interfejsy: GraphSearch i GraphScorer, a GraphScorer to tylko dwa. W źródle Java: 'publiczny interfejs GraphScorer { double scoreDag (Graph dag); } ' –