Domanda

Non ho dati in forma LISP e ho bisogno di elaborarli in RapidMiner. Sono nuovo di LISP e RapidMiner pure. RapidMiner non accetta il LISP (credo che sia perché è linguaggio di programmazione) quindi probabilmente ho bisogno in qualche modo a forma di convertire LISP in formato CSV o qualcosa di simile. Piccolo esempio di codice:

(def-instance Adelphi
   (state newyork)
   (control private)
   (no-of-students thous:5-10)
   ...)
(def-instance Arizona-State
   (state arizona)
   (control state)
   (no-of-students thous:20+)
   ...)
(def-instance Boston-College
   (state massachusetts)
   (location suburban)
   (control private:roman-catholic)
   (no-of-students thous:5-10)
   ...)

sarei davvero grato per qualsiasi consiglio.

È stato utile?

Soluzione

Si può fare uso di fatto che parser di Lisp è disponibile per l'utente Lisp. Un problema con questi dati è che alcuni valori contengono due punti, viene utilizzato con il separatore nome del pacchetto in Common Lisp. Ho fatto qualche lavoro Codice Common Lisp per risolvere il problema, ma ho avuto per aggirare il problema menzionato definendo pacchetti adeguati.

Ecco il codice, che, naturalmente, deve essere esteso (seguendo gli stessi schemi che sono già utilizzati in esso) per tutto quello che hai lasciato fuori nel esempio nella tua domanda:

(defpackage #:thous
  (:export #:5-10 #:20+))
(defpackage #:private
  (:export #:roman-catholic))

(defstruct (college (:conc-name nil))
  (name "")
  (state "")
  (location "")
  (control "")
  (no-of-students ""))

(defun data->college (name data)
  (let ((college (make-college :name (write-to-string name :case :capitalize))))
    (loop for (key value) in data
       for string = (remove #\| (write-to-string value :case :downcase))
       do (case key
            (state (setf (state college) string))
            (location (setf (location college) string))
            (control (setf (control college) string))
            (no-of-students (setf (no-of-students college) string))))
    college))

(defun read-data (stream)
  (loop for (def-instance name . data) = (read stream nil nil)
     while def-instance
     collect (data->college name data)))

(defun print-college-as-csv (college stream)
  (format stream
          "~a~{,~a~}~%"
          (name college)
          (list (state college)
                (location college)
                (control college)
                (no-of-students college))))

(defun data->csv (in out)
  (let ((header (make-college :name "College"
                              :state "state"
                              :location "location"
                              :control "control"
                              :no-of-students "no-of-students")))
    (print-college-as-csv header out)
    (dolist (college (read-data in))
      (print-college-as-csv college out))))

(defun data-file-to-csv (input-file output-file)
  (with-open-file (in input-file)
   (with-open-file (out output-file
                        :direction :output
                        :if-does-not-exist :create
                        :if-exists :supersede)
     (data->csv in out))))

La funzione principale è di dati-file-to-CSV, che può essere chiamato con (data-file-to-csv "path-to-input-file" "path-to-output-file") in Lisp REPL comune dopo il caricamento di questo codice.

EDIT: alcune riflessioni aggiuntive

Si sarebbe in realtà essere più facile, invece di aggiungere definizioni di pacchetto per tutti i valori con i due punti, per fare una ricerca di espressioni regolari e sostituire sui dati per aggiungere le virgolette ( ") attorno a tutti i valori. Questo renderà Lisp li analizza come stringhe subito. in tal caso, il for string = (remove #\| (write-to-string value :case :downcase)) linea potrebbe essere rimossa e string essere sostituito con value in tutte le linee della dichiarazione case.

A causa della elevata la regolarità dei dati, non dovrebbe nemmeno essere effettivamente necessario analizzare le definizioni Lisp correttamente a tutti. Invece, si può solo estrarre i dati con le espressioni regolari. Un linguaggio particolarmente adatto per la trasformazione regex-based di file di testo dovrebbe essere più che bene per quel lavoro, come AWK o Perl.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top