entfernen von rowID

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

Moderatoren: EDi, jogo

retep
Beiträge: 99
Registriert: Do Sep 06, 2018 7:50 pm

entfernen von rowID

Beitrag von retep »

Hallo,

ich wollte um Hilfe in folgender Angelegenheit bitten im Anhang ist eine Textdatei aufgeführt. Auf den ersten Blick enthält diese nur eine Spalte. Mit dem Befehl:

Code: Alles auswählen

head(df1)
werden jedoch auch die Zeilennamen korrekt angezeigt. Mein Problem ist, ich möchte zur Weiterverarbeitung die automatisch erstellen Zeilennumern entfernen. Trotz intensiven Google fand ich keine befriedigende Lösung. Eine Lösung wäre diese hier:

Code: Alles auswählen

library(data.table)
df1 = rowid_to_column(df1, var = "rowid"); df1
Aber ich will die Nummer weg haben und die Namen der Zeilen behalten! Also genau anders rum.

Kann mir da jemand weiterhelfen?

Vielen Dank im Vorraus,

retep
Dateianhänge
df1.txt
(659 Bytes) 87-mal heruntergeladen
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: entfernen von rowID

Beitrag von bigben »

Hallo retep,

da müssen wir die Aufgabenstellung erst klären. Führen wir folgendes aus:

Code: Alles auswählen

dat <- read.table("http://forum.r-statistik.de/download/file.php?id=1609", header = TRUE)

str(dat)
print(dat)
Jetzt haben wir einen dataframe der enthält eine einzige Spalte mit einer Häufung der Werte "marl", "os" und "phos". Insgesamt 150 Zeilen. Dieser dataframe enthält keine Zeilennummern. Es ist eine Eigenart der Funktion print() dazu Zeilennummern auszugeben aber die sind im Datensatz selbst nicht enthalten. Also auch nicht im Weg, wenn DU irgendwas weiterverarbeiten willst. Welche Art von Weiterverarbeitung schwebt Dir denn vor?

Wenn Du zum Beispiel mit "summary" eine Zusammenfassung aller Spalten anzeigen lässt erhälst Du nur eine Summary der Lithology-Spalte, nichts mit Zeilennummern:

Code: Alles auswählen

summary(dat)
LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: entfernen von rowID

Beitrag von jogo »

Hallo Peter,

hast Du die Datei so eingelesen?

Code: Alles auswählen

library("data.table")
df1 <- fread("http://forum.r-statistik.de/download/file.php?id=1609")
Dabei werden die Zeilen nur durchnummeriert.
Was passt Dir an den Nummern nicht?
Notfalls kann man Zeilennammen immer löschen mit

Code: Alles auswählen

rownames(df1) <- NULL
Gruß, Jörg
retep
Beiträge: 99
Registriert: Do Sep 06, 2018 7:50 pm

Re: entfernen von rowID

Beitrag von retep »

Hej,

erstmal vielen Dank für das schnelle Feedback. Ich habe die Datei nicht eingelesen! Sondern mir über diesen Workaround aus einem kompletten Datensatz die Zeilennamen erstellt.

Code: Alles auswählen

# first create a matrix
df <- as.matrix(OriginalData)
Dann erstelle ich die Zeilennamen aus der ersten Spalte "Lithology"

Code: Alles auswählen

 #Mit diesem Code hier vermeide ich die Fehlermeldung, das Duplikate in den Zeilen auftauchen!
 # Insert the Lithology  row
rownames(df)=paste(c(1:nrow(df)),df[,1]); df1    # [,1] oder [,10] ist die Spalte welche die Clustername später bilden
fix(df)
# back transform to a data frame

Code: Alles auswählen

df <- as.data.frame(df); df
Aus diesem frame habe ich mir eine Kopie erstellt und dann nur noch von diesem Frame ein Ausriss (1. Spalte) erstellt. Es geht nur ums Prinzip hier. Diese Mini datei habe ich hier geladen.
Idee dahinter:
Ich will den Datensatz in shiny verwenden um dann eine automatische Abfrage nach der Lithology zu machen. Normalerweise könnte man auch die Grafiken in ggplot über facet.wrap in unterschiedliche Lithologien/ Kategorien einteilen. Das möchte ich aber ausdrücklich nicht. Sondern ich wollte in Shiny innerhalb der Oberfläche (UI) den Input erstellen z.Bsp.pickerInput, selectINput usw. Und dazu brauche ich wohl die rownames

Hier ein Beispiel aus der Anleitung:

library(shiny)
library(shinyWidgets)

Code: Alles auswählen

ui <- fluidPage(
br(),
pickerInput(
inputId = "p1",
label = "Default",
multiple = TRUE,
choices = rownames(mtcars),
selected = rownames(mtcars)[1:5]
Jetzt habe ich meine rownames aber blöderweise die rowID mit dazu. Diese muss weg! Sonst funktioniert die Abfrage nicht! Könnte man das nicht mit "stringi" machen. Ich wühle mich gerade durch die Anleitung. Aber alles was ich sehe, ist das die Abfragen nur über die Spalten funktionieren aber nicht für die Zeilen????

Meiner Meinung nach???????
retep
Beiträge: 99
Registriert: Do Sep 06, 2018 7:50 pm

Re: entfernen von rowID

Beitrag von retep »

Hallo alle zusammen,

Nochmal ein kleiner Zusatz zu meinem letzen Eintrag. Wenn man sich denn Beispiel Datensatz aus der library (cars) den Unterdatensatz "mtcars" anschaut:

Code: Alles auswählen

fix(mtcars)
Dann sieht man dass dort in den der "unsichtbaren" Spalte, "row.names, die Typbezeichnung der Autos ohne Zeilennummer erfolgt. Im Gegensatz zu meinen row.names in diesem Beispiel taucht die id nummer auf.

Meine Frage: Wie haben die Autoren das gemacht?

Denn nur über die Zeilennamen kann die Klassifizierung der Autotypen erfolgen. Ähnlich wie bei mir. Ich würde gerne die Graphiken getrennt nach Lithology einzeln ausweisen. In ggplot ist das über den facet_wrap Befehl prinzipiell auch möglich aber in diesem Fall bekomme ich in einem Plot alle Lithologien getrennt in Spalten präsentiert. Was auch okay ist. Aber in einigen Fällen wäre eine einzelne Darstellung mit nur einer Lithologie besser.

Gibt es denn noch Ideen, wie ich die rowid ohne idnummer erstellen kann?

Würde mich sehr freuen und ich bin mir sicher, dass sich bestimmt andere Interessenten ebenfalls für die Lösung interessieren würden.

Vielen Dank für die Mühe und den Aufwand.
retep
retep
Beiträge: 99
Registriert: Do Sep 06, 2018 7:50 pm

Re: entfernen von rowID

Beitrag von retep »

Hier ist das Beispiel wie ich rownames ohne die ID erstelle:

Code: Alles auswählen

# Convert between row names and column --------------------------------
mtcars_tbl <- rownames_to_column(mtcars, var = "car") %>% as_tibble()
mtcars_tbl
Ist das getan folgt der letzte Schritt:

Code: Alles auswählen

column_to_rownames(mtcars_tbl, var = "car") %>% head()
Eigentlich ganz einfach! Die rownames sind hier tatsächlich ohne ID Nummer! Zu finden ist dieses Beispiel hier:

https://tibble.tidyverse.org/reference/rownames.html

Aber dieses Beispiel funktioniert nur, wenn jede Zeile unterschiedlich ist. Ist dies nicht gegeben, so wie in meinem Fall, kommt der Fehler:
Fehler: Column name `Lithology` must not be duplicated.

Deswegen muss ich den Umweg über die Matrix gehen. Aber hier werden die rownumbers mit geschrieben, d.h. in eine Spalte rowid und rowname zusammen.

Nochmals meine Frage: Wie bekomme ich den Zeilennamen getrennt von der Nummer oder anders gefragt, gibt es einen Weg die Zelle zu trennen in nummer raus & name drin lassen.

Vielen Dank für Eure Hilfe,

retep
bigben
Beiträge: 2771
Registriert: Mi Okt 12, 2016 9:09 am

Re: entfernen von rowID

Beitrag von bigben »

Hallo retep,

um der Verständlichkeit willen wäre es vielleicht am besten, wenn Du ein reproduzierbares Beispiel postest. Im Eingangspost hast du ein File geschickt, aber wie aus diesem File ein Dataframe wird, der Dein Problem repräsentiert, dazu hast Du nichts geschrieben. Die jeweiligen Rückfrage/Vorschläg von jogo und mir waren wohl nicht zielführend. Dann hast Du Code gepostet, der sich auf eine Matrix aus OriginalData bezieht, aber wir haben keine OriginalData. Warum genau Du den Umweg über as.matrix brauchst habe ich nicht wirklich verstanden und danach postest Du als Beispiel mtcars, das aber anscheinend gut funktioniert und mit dem sich das Problem wohl nicht reproduzieren lässt? Oder habe ich das falsch verstanden? Ehrlich gesagt weiß ich nicht Mal, ob wir derzeit ein Problem für einen klassischen data.frame, für ein tibble oder für ein data.table lösen sollen.

Am einfachsten wäre es wahrscheinlich, ein dput von einem repräsentativen Ausgangsdatensatz und eine Darstellung dessen, was daraus extrahiert werden soll zu posten.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
retep
Beiträge: 99
Registriert: Do Sep 06, 2018 7:50 pm

Re: entfernen von rowID

Beitrag von retep »

Hallo bigben,

erstmal vielen Dank für die Rückmeldung und die Nachsicht mit mir. Ich muss ausdrücklich entschuldigen, kein komplett nachvollziehbares Beispiel angefügt zu haben. Das ist natürlich eine unerlässliche Voraussetzung! Steht auch überall!!!!

Also nochmal ganz von vorn:

Gut dass ich in der Vorbereitung des scripts hierfür nochmal ein bisschen nachdenken konnte über das was ich will und das was ich bis jetzt als Ergebnis habe.

Kurz gesagt für die Arbeitsgruppe will ich in shiny in script erstellen, was es uns zum Anfang erlaubt schneller an die Plots (Deskriptive Statistik), später auch multivariate Statistik zu kommen. Herfür habe ich eine Beispiel Datei (df) angehängt.

Das Ziel ist z. Bsp. einen Boxplot oder Histogramm für jeden Horizont einzeln getrennt nach Element ausweisen zu können. Zum Beispiel um Elemente über einzelne Horizonte zu vergleichen.

Geht man über dplyr und ggplot ist es ziemlich einfach.

Code: Alles auswählen

library(tidyverse)
df%>%
  select(Horizont, Element_1, Element_2,Element_3)%>%
  reshape2::melt(id.var=c("Horizont"))%>%
  rename (Element = variable,
           Value = value)%>%
  filter(Horizont == "Horizont B")%>%
  ggplot(aes(x = "", y= Value)) +  
  geom_boxplot(notch = TRUE, color = "#e9ecef", fill="#69b3a2", outlier.colour = "red", width = 0.6)+
  stat_summary(fun = "mean", color = "black", shape = 8) +
  geom_jitter(alpha = 0.8, width = 0.2, height = 0, color = "orange") +
  facet_wrap( ~ Element, scales = 'free_y', nrow = 1)+
  #coord_flip()+
  #ggtitle("Boxplot") +
  labs(title = "Boxplot - Horizont 'B'",
       subtitle = "Black stars: mean value
Red dots: outlier",
       caption = "",
       tag = "")+
  scale_y_continuous(name ="[wt. %]")+
  theme_ipsum() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())+
  theme(plot.title = element_text(size=15))
Oben die Original Datei und als Ergebnis kommt der Plot! Durch die Umwandlung in eine Lang-Version kann ich in jede gewünschte Richtig filtern!
In shiny funktioniert das nicht! Um dasselbe Ergebnis in shiny zu erzielen, muss ich die rownames erzeugen. Diese dann adressieren in shiny.

Das erzeugen von rownames geht im Beispieldatensatz von mtcars über den Befehl:

Code: Alles auswählen

head(mtcars)
mtcars_tbl <- rownames_to_column(mtcars, var = "car")  %>%
              as_tibble()%>%
              head(); mtcars_tbl

Code: Alles auswählen

has_rownames(mtcars)
bei meinem Datensatz kommt eine Fehlermeldung:

Code: Alles auswählen

df_tbl <- rownames_to_column(df, var = "Horizont")%>%
               as_tibble()%>%
                head(); df_tbl
Fehler:
Fehler: Column name `Horizont` must not be duplicated
.

Die Erklärung für diesen Fehler wird in der Literatur beschrieben!

Ich habe aber trotzdem einen Weg gefunden, trotz der Duplikate die rownames zu erstellen:

Code: Alles auswählen

head(df)
# Check is there rowname
has_rownames(df)
# Insert the "Horizont" as row
# first create the matrix
# can be skipped, not entirely necessary - works with a dataframe too
df <- as.matrix(df); df
# set rownames
rownames(df)=paste(c(1:nrow(df)),df[,1]); df    # [,1] oder [,10] ist die Spalte welche die Clustername später bilden
# what type of data
class(df)
# back transform to a data frame
# can be skipped, not entirely necessary - works with a dataframe too
df <- as.data.frame(df); df
# Check is there rowname
has_rownames(df)
# rownames contain rowid  + rowname in one column or cell
fix(df)
Wenn man jetzt den letzten Befehl anwendet, sieht man sofort, dass in den rownames die rowid + rowname geschrieben wurde. Meine Frage lautet nun; Wie bekomme ich die rowid da wieder raus. Ich komme nicht an diese Information ran.

Auf der anderen Seite habe ich festgestellt, das in shiny jede einzelne Zeil indiziert wird. Doch dazu später. Also nochmal:

Das primäre Ziel ist die oben gezeigte Grafik in shiny darstellen zu lassen. Mit oder ohne rownames....

Ich freue mich über jeden Hilfe und Gedanken um dieses Problem zu lösen.

Vielen Dank!

retep
Dateianhänge
df.txt
(4.05 KiB) 86-mal heruntergeladen
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: entfernen von rowID

Beitrag von EDi »

In shiny funktioniert das nicht! Um dasselbe Ergebnis in shiny zu erzielen, muss ich die rownames erzeugen. Diese dann adressieren in shiny.
:shock:

Erklär das mal bitte... (bevor wir hier ein scheinproblem lösen...)
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.
retep
Beiträge: 99
Registriert: Do Sep 06, 2018 7:50 pm

Re: entfernen von rowID

Beitrag von retep »

Hallo Edi,

hier das zugehörige Shiny script:

Code: Alles auswählen

library (shiny)

ui <- fluidPage(
  titlePanel(title = h4(" Shiny App", align = "center")),
  sidebarLayout(
    sidebarPanel(
      tags$h2("Select / Deselect all"),
      pickerInput(
        inputId = "datatable",
        label = "Select a element",
        choices = colnames(df [2:4]),
        #choices = rownames(df),
        multiple = TRUE,
        options = list(`actions-box` = TRUE)
      ),
      textOutput(outputId = "res_classic")),
      
      mainPanel(
        tabsetPanel(type = "tab",
                    tabPanel("Boxplot", plotOutput("box")))
        
      ))
    )


server <- function(input, output, session) {
  
  # The boxplot
  output$box = renderPlot({
    ggplot(df, aes(x ="", y=.data[[input$datatable]])) +  
      geom_boxplot(notch = TRUE, color = "#e9ecef", fill="#69b3a2", outlier.colour = "red", width = 0.6)+
      stat_summary(fun = "mean", color = "black", shape = 8) +
      geom_jitter(alpha = 0.8, width = 0.2, height = 0, color = "orange") +
      facet_wrap( ~ Horizont, scales = 'free_y', nrow = 1)+
      #coord_flip()+
      #ggtitle("Boxplot") +
      labs(title = "Boxplot",
           subtitle = "Black stars: mean value
Red dots: outlier",
           caption = "",
           tag = "")+
      theme_ipsum() +
      theme(axis.title.x=element_blank(),
            axis.text.x=element_blank(),
            axis.ticks.x=element_blank())+
      theme(plot.title = element_text(size=15))
    
  }, res = 96, height = 600, width = 900 )
  
}

shinyApp(ui, server)
Wenn ich bei choices "umschalte" zwischen rownames und columnames dann erscheint bei columnames der Plot. Aber ich kann "nur" elementweise über alle 3 Horizonte vergleichen. Es ist nicht möglich nur einen Horizont mit 3 Elementen untereinander zu vergleichen.

Schalte ich die rownames frei - dann erscheinen alle zeilen inklusive der Zeilennummer! Ich hatte eigentlich vor einen einzelnen Horizont anzusprechen und wie in dem dplyr/ ggplot Beispiel beschrieben, alle 3 Elemente über einen Horizont hinweg zu vergleichen!

Meine Frage:

1. Geht das überhaupt mit meiner Herangehensweise?
2. Oder sitze ich hier sogar einem Denkfehler auf.
3. Gibt es eine alternative Herangehensweise um zum gewünschten Ergebnis zu kommen?

Vielen Dank für die Geduld & Hilfe,

retep
Antworten