Seite 1 von 1

import von {(...):..} Datei-Format

Verfasst: Do Nov 30, 2017 2:47 pm
von smallFish
Hallo zusammen,

ich möchte eine .out- Datei in R importieren, in welcher die Daten in folgender Form gespeichert sind:

result(a,b,c) := data
{ ( 0, a, 1 ) : 10, ( 0, a, 2 ) : 12, ( 0, a, 3 ) : 13}
}

Inhaltlich würde es diesem Format entsprechen (jede Zelle ein Wert mit Überschriften)

a,b,c, result,
0,a,1, 10,
0, a, 2, 12,
0, a, 3, 13

Weiß jemand, wie ich die 1. Variante möglichst elegant in Variante 2 überführen kann?
Oder ist dieses {( ): , (): }- Format als Standardformat in R bekannt und ich brauche nur ein bestimmtes Paket zum einlesen? Die Werte in den runden Klammern bezeichnen jeweils die Indizes, der Wert nach dem Doppelpunkt den Wert mit dem ich gerne in R weiterrechnen möchte.

Vielen Dank für Eure Hilfe!

Viele Grüße
Eleni

Re: import von {(...):..} Datei-Format

Verfasst: Fr Dez 01, 2017 12:57 pm
von jogo
Hallo Eleni,

willkommen im Forum!
Welches Programm erzeugt denn einen Output in so einem Format?
Vielleicht hat dieses Programm auch noch andere Möglichkeiten für den Export von Daten.

Gruß, Jörg

Re: import von {(...):..} Datei-Format

Verfasst: Fr Dez 01, 2017 2:18 pm
von smallFish
Hallo Jörg,

die Datei kommt von Aimms, einer Optimierungssoftware - wahrscheinlich könnte man es anpassen, ich weiß nur im Moment noch weniger wie das dort gehen sollte als in R.
Ich hatte gehofft, dass in R das Format vielleicht eh schon bekannt ist oder zumindest sehr viel flexibler behandelt werden kann als mit Aimms.

Viele Grüße
Eleni

Re: import von {(...):..} Datei-Format

Verfasst: Fr Dez 01, 2017 9:11 pm
von EDi
Hier ein parser für deine Datei:

Code: Alles auswählen

# create example file
f <- tempfile()
cat("result(a,b,c) := data
{ ( 0, a, 1 ) : 10, ( 0, a, 2 ) : 12, ( 0, a, 3 ) : 13}
}", file = f)


# parser to use
#' @param file path to file
my_parser <- function(file) {
  dat <- readLines(file, warn = FALSE)
  l <- length(dat)
  
  header <- dat[1]
  end <- gsub('^(.*)\\(.*$', '\\1', header)
  vars <- strsplit(gsub('^.*\\((.*)\\) :=.*$', '\\1', header), ',')[[1]]
  colnams <- c(vars, end)
  
  data <- dat[2:(l-1)]
  data <- gsub('\\{ |\\}', '', data)
  data <- strsplit(data, ', \\(')[[1]]
  data <- gsub('\\(|\\)', '', data)
  data <- gsub('  :', ',', data)
  data <- unlist(strsplit(data, ' ,'))
  data <- strsplit(data, ',')
  
  out <- as.data.frame(do.call(rbind, data))
  colnames(out) <- colnams
  return(out)
}

my_parser(f)
   a  b  c result
1  0  a  1     10
2  0  a  2     12
3  0  a  3     13
Wie es funktioniert, darfst du selbst rausfinden :mrgreen:
(Zeile für Zeile durchen und schauen was sich ändern, ist ein bisschen regex dabei...)

Re: import von {(...):..} Datei-Format

Verfasst: Mo Dez 04, 2017 11:50 am
von smallFish
Hallo Edi,

vielen Dank für den Code!

Ich muss leider doch noch was dazu fragen, weil´s bei mir noch nicht ganz funktioniert, sorry.
Das mag aber daran liegen, das ich mit solchen Codes bisher noch nicht gearbeitet habe und irgendeinen Simpelfehler mache... (oder brauche ich noch ein bestimmtes Paket?):

1. Wenn ich deine Zeilen im Ganzen markiere, läuft´s durch, wenn ich sie einzeln durchgehe nicht. (--> z.B. Error: object 'dat' not found)
Insdofern scheitere ich gerade auch an der Selbsterarbeitung des Codes.

2. Sehe ich das richtig, dass ich mein eigentliches Datentextfile per

Code: Alles auswählen

f <- tempfile()
f <- daten 
einfüge?

Da bekomme ich folgenden Fehler in der Console:

Code: Alles auswählen

> my_parser(f)
Error in readLines(file, warn = FALSE) : 'con' is not a connection
Called from: readLines(file, warn = FALSE)
Browse[1]> 
Und folgendes:

Code: Alles auswählen

function (con = stdin(), n = -1L, ok = TRUE, warn = TRUE, encoding = "unknown", 
	skipNul = FALSE) 
{
	if (is.character(con)) {
		con <- file(con, "r")
		on.exit(close(con))
	}
	.Internal(readLines(con, n, ok, warn, encoding, skipNul))
}
Über einen Tipp, was mir das sagen sollte, wäre ich sehr dankbar!

Viele Grüße
Eleni

Re: import von {(...):..} Datei-Format

Verfasst: Mo Dez 04, 2017 11:03 pm
von EDi
Probier's mal so:

Code: Alles auswählen

 
 dat <- readLines('<PfadzurDatei>', warn = FALSE)
  l <- length(dat)
  
  header <- dat[1]
  end <- gsub('^(.*)\\(.*$', '\\1', header)
  vars <- strsplit(gsub('^.*\\((.*)\\) :=.*$', '\\1', header), ',')[[1]]
  colnams <- c(vars, end)
  
  data <- dat[2:(l-1)]
  data <- gsub('\\{ |\\}', '', data)
  data <- strsplit(data, ', \\(')[[1]]
  data <- gsub('\\(|\\)', '', data)
  data <- gsub('  :', ',', data)
  data <- unlist(strsplit(data, ' ,'))
  data <- strsplit(data, ',')
  
  out <- as.data.frame(do.call(rbind, data))
  colnames(out) <- colnams
  out
Einfach den Pfad einfügen und Zeile für Zeile durchlaufen lassen.
Ich hatte das in eine Funktion gepackt, um später das programmieren damit einfacher zu machen...
Insdofern scheitere ich gerade auch an der Selbsterarbeitung des Codes.
Wenn es in irgendeiner Zeile einen Fehler gibt, sofort danach schauen was er bedeutet und woran das liegt...
2. Sehe ich das richtig, dass ich mein eigentliches Datentextfile per
f <- tempfile()
f <- daten
einfüge?
Nein, ich habe damit nur eine Beispieldatei erstellt. Du hast ja leider keine mitgeliefert und ich musste etwas haben zum austesten - falls meine Annahmen nicht passen, musst du das selbst anpassen.