Seite 1 von 1

Schleife für die Verwendung verschiedener Spalten eines Dataset

Verfasst: Mi Dez 30, 2020 3:41 pm
von Nickels
Hallo zusammen,

leider plagt mich ein recht simples Problem, dessen Lösung für die Meisten hier sicher kein Problem ist. Derzeit bin ich noch nicht so tief eingetaucht in R und stehe auf dem Schlauch...

Problem in Kurzfassung:

Wie kann ich einen String so konvertieren, dass er als Spalte erkannt wird?
Oder gibt es einen eleganteren Weg?

Problem in Langfassung:

Ich habe ein Dataset bestehend aus 300k Datensätzen und 50 Spalten.
Um das Fehlerpotenzial durch manuelle Eingaben zu reduzieren, würde ich gerne eine Datenanalysefunktion in einer Schleife ausführen und somit 50 manuelle Aufrufe vermeiden.
Dies versuche ich durch einen Vektor, der die Namen der benötigten Spalten beinhaltet. Wie es aussieht fehlt jedoch die Referenz zu der entsprechenden Spalte aufgrund seines Datentyps.

Code: Alles auswählen

library(mosaic)
array_variablen <- c("Faktor_Spalte1", "Faktor_Spalte2", "Faktor_Spalte3")

testfunktion <- function(wert){
  print(tally(x = paste(sep="", "tabelle$", wert),  format = 'proportion'))
}

for(i in 1:length(array_variablen)){
  testfunktion (array_variablen[i])
}
Über eine Antwort würde ich mich sehr freuen :)

Viele Grüße und guten Rutsch
Nickels

Re: Schleife für die Verwendung verschiedener Spalten eines Dataset

Verfasst: Mi Dez 30, 2020 4:01 pm
von bigben

Code: Alles auswählen

> array_variablen <- c("Faktor_Spalte1", "Faktor_Spalte2", "Faktor_Spalte3")
> 
> testfunktion <- function(wert){
+     print(tally(x = paste(sep="", "tabelle$", wert),  format = 'proportion'))
+ }
> 
> for(i in 1:length(array_variablen )){
+     testfunktion (array_variablen [i])
+ }
Fehler in tally(x = paste(sep = "", "tabelle$", wert), format = "proportion") : 
  konnte Funktion "tally" nicht finden
> 
> 
> 
> library(dplyr)

Attache Paket: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

> array_variablen <- c("Faktor_Spalte1", "Faktor_Spalte2", "Faktor_Spalte3")
> 
> testfunktion <- function(wert){
+     print(tally(x = paste(sep="", "tabelle$", wert),  format = 'proportion'))
+ }
> 
> for(i in 1:length(array_variablen )){
+     testfunktion (array_variablen [i])
+ }
Fehler in tally(x = paste(sep = "", "tabelle$", wert), format = "proportion") : 
  unbenutztes Argument (format = "proportion")
> 

Re: Schleife für die Verwendung verschiedener Spalten eines Dataset

Verfasst: Do Dez 31, 2020 10:05 pm
von EDi
Was willst du denn erreichen?

Code: Alles auswählen

paste(sep="", "tabelle$", wert)
Es ist In den allermeisten Fällen (eigentlich allen) eine schlechte Idee Code aus strings zusammen setzt (und dann mit parse() und eval() ausführt).

Man kann das (nennt sich "Meta-Programmierung") mit R machen und es ist meiner Meinung nach eine RIESEN Stärke von R gegenüber anderen Programmiersprachen. ABER: Es ist auch mit das komplexeste in R und man kann diese Macht nur mit viel Rfahrung nutzen.

Hier mein Ein Beispiel (deins läuft ja nicht, wie BigBen schon gezeit hat):

Ich habe eine Tabelle mit 4 Spalten und hätte gerne für jede Spalte die Anzahl der unterschiedlchen werte je Spalte.
Ich habe mal 3 Arten gezeigt wie man das machen kann.
Einmal wie du es machst (code zusammenpasten), einmal mit Schleife und einmal funktionell:

Code: Alles auswählen

# Fnx ---------------------------------------------------------------------

#' Compute the number of unique values in a vector
#' @examples 
#' lu(c(1, 1, 2, 2, 3))
lu <- function(x){
  stopifnot(is.vector(x))
  length(unique(x))
}

# Data --------------------------------------------------------------------

df <- data.frame(a = 1:10, 
                 b = rep(seq(1, 10, 2), 2),
                 c = rep(seq(1, 10, 5), 5),
                 d = 1)


# Solutions ---------------------------------------------------------------

# 1. For loop + eval(parse) [=your solution]

for (i in names(df)) {
  code <- paste0("lu(", paste0("df$", i), ")")
  print(eval(parse(text = code)))
}

# 2. loop + '['
for (i in names(df)) {
  print(lu(df[[i]]))
}

# 3. Functional programming
lapply(df, lu)
Mit R kann man auch wunderbar funktional programmieren. Das würde ich hier machen, ist am elegantesten, einfachsten zu verstehen und vermutlich auch am schnellsten.
Derzeit bin ich noch nicht so tief eingetaucht in R und stehe auf dem Schlauch...
Ich rate dir dich noch etwas mit den Basics zu beschäfftigen, sonst schießt du mit Kanonen auf Spatzen...