Seite 1 von 1

if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 8:48 am
von Till
Liebe R-Community,
nach langem Hin und Her haben wir uns (als Neueinsteiger in R) entschieden unsere Daten nicht mit r-markdown sondern mittels officer in einem Word-Dokument zu präsentieren. Soweit so gut, jetzt mein Problem: Ich erzeuge im Vorfeld verschie-dene flextables die ich dann ich das Word-Dokument einbinde. Nun möchte ich jedoch anhand eine if-else-Bedingung Tabellen selektieren, die dargestellt werden sollen. Der Code sollte meiner Meinung nach etwa so aussehen:

Code: Alles auswählen

# Einlesen der Word-Vorlage                 
docTest <- read_docx("C:/Vorlage.docx")
# Setzen der Bedingungsvariable aus den Tabellendaten
wert <- as.integer(Daten_Tabelle_A[nrow(Daten_Tabelle_A), 2])   
# if-Bedingung
if (wert < 3) {                                                                             
      body_add_par("", style = "Normal")                                       # Leerzeile einfügen
    } else {
      body_add_flextable(Tabelle_A) %>%                                      # Tabelle einfügen
            }     %>%
# Ausgabe
print(docTest, target = "C:/Dateiname.docx")   



Wenn ich das so durchlaufen lassen erhalte ich folgendes:

Code: Alles auswählen

> docTest <- read_docx("C:/Vorlage.docx")
>     wert <- as.integer(Daten_Tabelle_A[nrow(Daten_Tabelle_A), 2])  
>     if (wert < 3){
+       body_add_par("Test", style = "Normal")
+     } else{
+       body_add_flextable(Tabelle_A) 
+       } 
Error in body_add_flextable(Tabelle_t6_8ac) : 
  inherits(x, "rdocx") is not TRUE
> 
>       print(docTest, target = "C:/Dateiname.docx")
[1] " C:/Dateiname.docx "
>

Das Worddokument wird erstellt, ist aber leer.
Ich vermute, dass innerhalb einer if-else-Bedingung keine officer-Befehle funktionieren.

Vielleicht hat jemand ähnliche Erfahrungswerte und kann mir ggfls. auch einen Lösungsansatz geben.

Vielen Dank

Till

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 10:23 am
von jogo
Hallo Till,

willkommen im Forum!
Mir scheint der Code bei

Code: Alles auswählen

    } else {
      body_add_flextable(Tabelle_A) %>%                                      # Tabelle einfügen
            }     %>%
nicht vollständig zu sein. (unvollständige pipes, außerdem das Vermischen mit Kontrollstrukturen)

Gruß, Jörg

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 1:05 pm
von Till
Hallo Jörg,

erstmal danke für die schnelle Antwort.
Wenn ich die pipes ergänze, unterschlängelt R mir direkt die '}' der else-Bedingung:

Error: unexpected '}' in:
" body_add_flextable(Tabelle_A) %>%
}"

Die ergänzte pipe nach der else-Bedingung führt zu derselben Fehlermeldung wie unsprünglich:

Error in body_add_flextable(Tabelle_A) :
inherits(x, "rdocx") is not TRUE


Ich weiß auch nicht genau, was du mit "Vermischen mit Kontrollstrukturen" meinst.

Für weitere Ideen bin ich weiterhin dankbar.
Gruß
Till

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 1:18 pm
von bigben
Till hat geschrieben: Mi Feb 26, 2020 1:05 pmError: unexpected '}' in:
" body_add_flextable(Tabelle_A) %>%
}"
Die Pipe %>% gehört da einfach nicht hin. Die ist dazu da, die von einem Kommando zurückgegebenen Daten an eine Funktion weiterzuleiten. Du leitest aber an Geschweifte-Klammer-Zu weiter. Das ist keine Funktion, also kann das auch nicht funktionieren. Was willst Du denn mit Deinen beiden Pipes erreichen?

LG,
Bernhard

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 1:23 pm
von jogo
Hallo Till,
Till hat geschrieben: Mi Feb 26, 2020 1:05 pm Ich weiß auch nicht genau, was du mit "Vermischen mit Kontrollstrukturen" meinst.
ich meine damit, den Ergebniswert einer if()-else-Konstruktion als Wert sofort weiter zu verwenden.
In vielen Programmiersprachen ist sowas nichtmal möglich. Da aber in R alles, was geschieht, ein Funktionsaufruf ist, könnte das sogar syntaktisch fehlerfrei sein. In Programmiersprachen, in denen dies nicht möglich ist, zählt die Konstruktion if-then-else eindeutig zu denen, die den Programmablauf kontrollieren/steuern.
Allerdings würde ich solche Konstruktionen stets vermeiden wollen - das ist so ein Gefühl, dass sich in ca. 40 Jahren Programmiererfahrung entwickelt hat.

Gruß, Jörg

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 1:30 pm
von bigben
Jörg meint sowas

Code: Alles auswählen

a <- 2

b <- if(a>0) 1 else 2
anstelle von

Code: Alles auswählen

if(a > 0) b <- 1 else b <- 2
ersteres ist in sog. funktionalen Programmiersprachen normal, kann aber unübersichtlich sein, wenn man in der zweiten Form zu denken gewöhnt ist. Im konkreten Fall erlaubt es uns nicht zu sagen, ob Deine zweite Pipe falsch ist oder ob die Zeile nur unvollständig ist.

LG,
Bernhard

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 3:07 pm
von Till
Danke für den Hinweis bigben,
bigben hat geschrieben: Mi Feb 26, 2020 1:18 pm Was willst Du denn mit Deinen beiden Pipes erreichen?
Die pipes waren einfach ein Denkfehler von mir. Ich habe sie einfach entfernt.

@Jörg und Bernhard

Ich habe mal versucht die Bedingung umzustricken (ich hoffe ihr meintet es so, mir fehlt ein wenig das Hintergrundwissen):

Code: Alles auswählen

docTest <- read_docx("C:/Vorlage.docx")                            # Einlesen der Word-Vorlage
wert <- as.integer(Daten_Tabelle_A[nrow(Daten_Tabelle_A), 2])      # Setzen der Bedingungsvariable aus den Tabellendaten
docTest <- if (wert < 3){                                          # if-Bedingung
                       body_add_par("", style = "Normal")          # Leerzeile einfügen
                      } else{
                         body_add_flextable(Tabelle_A)             # Tabelle einfügen
                         }     
print(docTest, target = "C:/Dateiname.docx")                       # Ausgabe
Leider kommt immer noch diese Fehlermeldung

Code: Alles auswählen

Error in body_add_flextable(Tabelle_t6_8ac) : 
  inherits(x, "rdocx") is not TRUE
Gruß, Till

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 6:14 pm
von jogo
Hallo Till,

ein kleines Problem, was ich hier beim Helfen im Forum habe, ist, dass ich viele Pakete, die von den Hilfesuchenden eingesetzt werden, nicht kenne und auch nur bei Vorliegen eines reproduzierbaren Beispiels installieren werde.
viewtopic.php?f=20&t=11
Till hat geschrieben: Mi Feb 26, 2020 3:07 pm

Code: Alles auswählen

docTest <- read_docx("C:/Vorlage.docx")                            # Einlesen der Word-Vorlage
wert <- as.integer(Daten_Tabelle_A[nrow(Daten_Tabelle_A), 2])      # Setzen der Bedingungsvariable aus den Tabellendaten
docTest <- if (wert < 3){                                          # if-Bedingung
                       body_add_par("", style = "Normal")          # Leerzeile einfügen
                      } else{
                         body_add_flextable(Tabelle_A)             # Tabelle einfügen
                         }     
print(docTest, target = "C:/Dateiname.docx")                       # Ausgabe
Leider kommt immer noch diese Fehlermeldung

Code: Alles auswählen

Error in body_add_flextable(Tabelle_t6_8ac) : 
  inherits(x, "rdocx") is not TRUE
Es sieht so aus als erwartet die Funktion body_add_flextable() an der Stelle, wo Tabelle_A steht, ein Objekt der Klasse rdocx erwartet.
Kannst Du das bitte prüfen:

Code: Alles auswählen

class(Tabelle_A)
Bitte lies auch den Hilfetext der Funktion body_add_flextable() gründlich.

Gruß, Jörg

Re: if-else-Bedingung im package officer

Verfasst: Mi Feb 26, 2020 6:30 pm
von EDi
Sollte es nicht sein:

Code: Alles auswählen

docTest <- body_add_flextable(docTest,Tabelle_A)
?

Aber ohne ein reproduzierbares Beispiel kann und will ich nicht mehr sagen.

Re: if-else-Bedingung im package officer

Verfasst: Do Feb 27, 2020 8:08 am
von Till
Danke EDi,

das war das Problem. Manchmal ist man echt betriebsblind.
Der vollständigkeitshalber hier ein reproduzierbares und jetzt auch funtionierendes Beispiel:

Code: Alles auswählen

# Bibliotheken
library("flextable")
library("officer")

# Erstellen ein flextable
Daten_A <- data.frame(A = c(1,2,2), B = c(4:6), C = c(7:9))
Tabelle_A <- flextable(Daten_A)

# Laden einer Wordvorlage
docWord <- read_docx("G:/Word_Vorlage.docx")  

variable <- as.integer(Daten_A[nrow(Daten_A), 1])

docWord <- if (variable < 3){
                body_add_par(docWord, "test", style = "Normal")  
                } else{
                    body_add_flextable(docWord, Tabelle_A)
                  }   
# Ausgabe
print(docWord, target = "G:/Word_Ergebnis.docx")
Danke auch an Jörg und Bernhard

Gruß, Till