Ausgabe einer mehrdimensionalen Summentabelle

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

talcom

Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von talcom »

Hallo Zusammen,

ich habe folgende Datenbank als Grundlage in meinem Coding.

Code: Alles auswählen

'data.frame':   5303 obs. of  9 variables:
 $ Metric.ID          : num  7156 7220 7220 7220 7220 ...
 $ Metric.Name        : Factor w/ 99 levels "Avoid accessing data by using the position and length",..: 51 59 59 
 $ Technical.Criterion: Factor w/ 25 levels "Architecture - Multi-Layers and Data Access",..: 4 9 9 9 9 9 9 9 9 9 ...
 $ RT.Snapshot.name   : Factor w/ 1 level "2017_RT12": 1 1 1 1 1 1 1 1 1 1 ...
 $ Violation.status   : Factor w/ 2 levels "Added","Deleted": 2 1 2 2 2 1 1 1 1 1 ...
 $ Critical.Y.N       : num  0 0 0 0 0 0 0 0 0 0 ...
 $ Grouping           : Factor w/ 29 levels "281","Bes",..: 27 6 6 6 6 7 7 7 7 7 ...
 $ Object.type        : Factor w/ 11 levels "Cobol Program",..: 8 7 7 7 7 7 7 7 7 7 ...
 $ Object.name        : Factor w/ 3771 levels "[S:\\SOURCES\\",..: 3771 3770 3769 3768 3767 3
Man sieht das es sich häufig um Factor Instanzen handelt, von denen ich mir jetzt ein paar Summen ausgeben lassen möchte bzw. die ich in Kombination bringen will.

Folgende Frage gibt es zu beantworten: Es gibt 25 Level von "Architektur Criterion". Zu jeder will ich wissen, wie viele Einträge es gibt mit den beiden Violation.Status Möglichkeiten (Added und Deleted), wenn man das Ganze noch nach "Critical.Y.N" unterscheidet. Hier ist neben der 0 auch der Wert 1 zulässig. Das Ganze sollte so in etwa aussehen.
Unbenannt.JPG
Folgendes Coding wurde mir bislang genannt, aber die Definition von Tab ist mir noch schleierhaft.

Code: Alles auswählen

for(i in 1:length(unique(b$Violation.status))){
  tab[[i]] <- xtabs(Critical.Y.N ~ Technical.Criterion + Object.type, b)
  names(dimnames(tab[[i]]))[2] <- paste("Violation.status", i)
}
Vllt habt Ihr einen Rat oder eine Idee. Danke

Gruß
Talcom
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von jogo »

Hallo Talcom,

willkommen im Forum"
talcom hat geschrieben: Fr Mai 04, 2018 7:30 am Folgende Frage gibt es zu beantworten: Es gibt 25 Level von "Architektur Criterion". Zu jeder will ich wissen, wie viele Einträge es gibt mit den beiden Violation.Status Möglichkeiten (Added und Deleted), wenn man das Ganze noch nach "Critical.Y.N" unterscheidet. Hier ist neben der 0 auch der Wert 1 zulässig. Das Ganze sollte so in etwa aussehen.
Mit Aussehen ist das immer so eine Sache - das kann immer noch viel Fummelei erfordern.
Wenn es nur um die Berechnung der Summen geht, ist xtabs() schon eine gute Variante. Vielleicht ist aggregate() etwas umfassender.
Folgendes Coding wurde mir bislang genannt, aber die Definition von Tab ist mir noch schleierhaft.

Code: Alles auswählen

for(i in 1:length(unique(b$Violation.status))){
  tab[[i]] <- xtabs(Critical.Y.N ~ Technical.Criterion + Object.type, b)
  names(dimnames(tab[[i]]))[2] <- paste("Violation.status", i)
}
Es sieht so aus, als ob tab ein Listen-Objekt sein soll. Was mich wundert, ist, dass beim Aufruf der Funktion xtabs() das Objekt für data= nicht nach dem Wert von i gefiltert wurde. Irgendwie habe ich die Vermutung, dass der Code in dieser Form nicht komplett ist. Auch nicht schön ist, dass die Namen für tab[[ i ]] so rangefriemelt werden.
m.E. hätte es so (oder so ähnlich) aussehen können:

Code: Alles auswählen

L <- split(b, b$Violation.status)
tab <- lapply(L, function(x) xtabs(Critical.Y.N ~ Technical.Criterion + Object.type, data=x))
... wobei mir wahrscheinlich die Struktur des Ergebnisobjektes nicht gefallen würde - aber das hängt davon, was man anschließend mit dem Objekt anstellen möchte.

Gruß, Jörg
talcom

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von talcom »

Hallo Jörg,

erstmal Danke für Deinen Beitrag.

Ich habe mal versucht Deinen Code mit zu verwenden und haben diesen in meinen Output eingefügt bzw. angepasst.

Code: Alles auswählen

# Output "Statistik" ------------------------------------------------------
  output$table2 <- DT::renderDataTable(DT::datatable({
    b <- db2
    L <- split(b, b$Violation.status)
    tab <- lapply(L, function(x) xtabs(Critical.Y.N ~ Technical.Criterion + Object.type, data=db2))
  })) 
Dabei übertrage ich zu Beginn meine db2 (wo die Ursprungswerte drin stehen) auf b und versuche dann mit Deinem Code weiter zu machen.
Leider bekomme ich dann bei der Ausführung folgenden Fehler: Error in DT::datatable: 'data' must be 2-dimensional (e.g. data frame or matrix)

Das Problem ist oft, dass in Beispielen im Netz immer einfach triviale Tabellen genutzt werden um komplexere Tabellen zu rendern. Ich befürchte das meine Ausgangstabelle, mit den Factoren schon sehr komplex ist.

Danke

Gruß
Talcom
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von jogo »

Hallo Talcom,
talcom hat geschrieben: Fr Mai 04, 2018 10:17 am Ich habe mal versucht Deinen Code mit zu verwenden und haben diesen in meinen Output eingefügt bzw. angepasst.

Code: Alles auswählen

# Output "Statistik" ------------------------------------------------------
  output$table2 <- DT::renderDataTable(DT::datatable({
    b <- db2
    L <- split(b, b$Violation.status)
    tab <- lapply(L, function(x) xtabs(Critical.Y.N ~ Technical.Criterion + Object.type, data=db2))
  })) 
Dabei übertrage ich zu Beginn meine db2 (wo die Ursprungswerte drin stehen) auf b und versuche dann mit Deinem Code weiter zu machen.
Leider bekomme ich dann bei der Ausführung folgenden Fehler: Error in DT::datatable: 'data' must be 2-dimensional (e.g. data frame or matrix)

Das Problem ist oft, dass in Beispielen im Netz immer einfach triviale Tabellen genutzt werden um komplexere Tabellen zu rendern. Ich befürchte das meine Ausgangstabelle, mit den Factoren schon sehr komplex ist.
die Funktion renderDataTable() kenne ich nicht. Nutzt Du irgendwelche zusätzlichen Pakete?

Unabhängig davon, Du hast doch in Deiner ersten Nachricht die Struktur eines Dataframes angegeben:

Code: Alles auswählen

'data.frame':   5303 obs. of  9 variables:
 $ Metric.ID          : num  7156 7220 7220 7220 7220 ...
 $ Metric.Name        : Factor w/ 99 levels "Avoid accessing data by using the position and length",..: 51 59 59 
 $ Technical.Criterion: Factor w/ 25 levels "Architecture - Multi-Layers and Data Access",..: 4 9 9 9 9 9 9 9 9 9 ...
 $ RT.Snapshot.name   : Factor w/ 1 level "2017_RT12": 1 1 1 1 1 1 1 1 1 1 ...
Wie lautet der Name dieses Objektes?
Mit diesem Dataframe müsstest Du eigentlich so arbeiten können:

Code: Alles auswählen

L <- split(DeinDataframe, DeinDataframe$Violation.status)
tab <- lapply(L, function(x) xtabs(Critical.Y.N ~ Technical.Criterion + Object.type, data=x))
Noch ein Hinweis:
Du hast das Argument FUN= in dem Aufruf von lapply() für Deinen Code eigenmächtig geändert.
Mit Deiner Änderung macht der Aufruf garantiert nicht das, was er soll.

Gruß, Jörg
talcom

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von talcom »

Das Object meines Datenframes lautet: db2
Die Struktur davon habe ich ja schon gepostet. Auf die Daten greife ich dann immer mit db2&xyz zu.

Folgende Librarys sind eingebunden:

Code: Alles auswählen

library(shiny)
library(dplyr)
library(DT)
Wie gesagt, ich bin Anfänger und habe mich nach Coding umgesehen. Zur Ausgabe einer Tabelle auf einem anderen Tab meines Dashboardes, verwende ich folgendes Coding:

Code: Alles auswählen

# Output "Filter"   -------------------------------------------------------  
  output$table1 <- DT::renderDataTable(DT::datatable({
    db2out <- db2
    if (input$MetIDlist != "All") {
      db2out <- db2out[db2out$Metric.ID == input$MetIDlist,]
    }
    if (input$TClist != "All") {
      db2out <- db2out[db2out$Technical.Criterion == input$TClist,]
    }
    if (input$RTlist != "All") {
      db2out <- db2out[db2out$RT.Snapshot.name == input$RTlist,]
    }
    if (input$Objectlist != "All") {
      db2out <- db2out[db2out$Object.type == input$Objectlist,]
    }
    if (input$VioStlist != "All") {
      db2out <- db2out[db2out$Violation.status == input$VioStlist,]
    }
    if (input$Critlist != "All") {
      db2out <- db2out[db2out$Critical.Y.N == input$Critlist,]
    }
    if (input$Grouplist != "All") {
      db2out <- db2out[db2out$Grouping == input$Grouplist,]
    }
    db2out[, input$Auswahl, drop = FALSE]
  }))
Das funktioniert auch und ich kann mit Filtern die Ausgabe gut steuern. Daher war der Versuch das für die Ausgabe meiner Summentabelle auf dem anderen Tab ähnlich zu machen.

Für bessere oder gar einfacherer Vorschläge bin ich aber jederzeit offen. Coding zu bewerten ist schwer für mich. Noch probiere und experimentiere ich viel, denn wie es scheint, gibt es im R viele Wege und Möglichkeiten mit Plugins etc.

Gruß
Talcom
Zuletzt geändert von jogo am Fr Mai 04, 2018 10:53 am, insgesamt 1-mal geändert.
Grund: tags
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von jogo »

Hallo Talcom,

renderDataTable() gehört zu shiny{} oder dem Drumherum. https://shiny.rstudio.com/reference/shi ... Table.html
Damit habe ich noch nie gearbeitet, deshalb werde ich zu dem Teil auch keine Auskunft geben.
Aus der Beschreibung der Funktion ist jedoch klar, dass das Ergebnis von expr ein zweidimensionales Objekt (Matrix oder Dataframe) sein muss.
Dies ist natürlich bei dem Ergebnis von lapply(...) nicht der Fall. Bei lapply(...) wird immer eine Liste als Ergebnis geliefert (siehe Abschnitt Value im Hilfetext).

Gruß, Jörg
talcom

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von talcom »

Wie würdest Du denn dann die Definition zur Ausgabe aufbauen damit es klappt?
Wenn in diesem Fall renderDataTable() der falsche Weg ist, wird es vllt. was Anderes geben was besser geeignet ist. Auch
wenn ich dazu UI.r bzw. Server.r an der Stelle verändern muss.
Was das Coding angeht, so habe ich mich an die Beispiele gehalten, wie diese auch unter https://shiny.rstudio.com/gallery/ veröffentlicht sind.
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von jogo »

Hallo Talcom,
talcom hat geschrieben: Fr Mai 04, 2018 11:53 am Wenn in diesem Fall renderDataTable() der falsche Weg ist, wird es vllt. was Anderes geben was besser geeignet ist. Auch
wenn ich dazu UI.r bzw. Server.r an der Stelle verändern muss.
Was das Coding angeht, so habe ich mich an die Beispiele gehalten, wie diese auch unter https://shiny.rstudio.com/gallery/ veröffentlicht sind.
zu den shiny-Sachen kann ich nichts sagen. Ich weiß nicht, was es dort für Möglichkeiten gibt.
Wie würdest Du denn dann die Definition zur Ausgabe aufbauen damit es klappt?
Ich möchte nochmal auf den Inhalt Deiner ersten Nachricht zurückkommen und habe mal folgendes vorbereitet:

Code: Alles auswählen

str(mtcars)
X <- xtabs(hp ~ cyl+vs+am, data=mtcars)
addmargins(cbind(X[,,1], X[,,2]), 2)
addmargins(cbind(X[,,1], X[,,2]))
sum(mtcars$hp)
Lass das mal in R laufen und schau mal, ob es etwa das ist, was Du möchtest.
Wenn ja, könnte die entsprechende Stelle in Deinem ursprünglichen Code so aussehen:

Code: Alles auswählen

Tab <- xtabs(Critical.Y.N ~ Technical.Criterion + Object.type + Violation.status, b)
addmargins(cbind(Tab[,,1], Tab[,,2]), 2)
Gruß, Jörg
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von EDi »

Für Shiny könntest du dir flextable mal anschauen:
https://davidgohel.github.io/flextable/ ... rview.html
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Ausgabe einer mehrdimensionalen Summentabelle

Beitrag von EDi »

xtable könnte auch interessant für solche Tabellen sein
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.

Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
Bild.
Antworten