elementweises Dividieren zweier Listen

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

Moderatoren: EDi, jogo

Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: elementweises Dividieren zweier Listen

Beitrag von Athomas »

ich wollte eine Liste durch eine andere Liste elementweise dividieren.
Ich will die Listen auch nicht in Vektoren oder ähnliches umwandeln.
Darf ich mal nach dem tieferen Sinn dieses „Problems“ fragen?
Oder handelt es sich dabei einfach um eine Fragenspende an die auskunftsbereite R-Gemeinschaft :lol: ?
Bill
Beiträge: 35
Registriert: Fr Mär 06, 2020 8:04 pm

Re: elementweises Dividieren zweier Listen

Beitrag von Bill »

Hallo,

Nach dem Motto: Warum zwei Listen in eine andere Datenstruktur umwandeln um eine simple mathematische Operation auszuführen, wenn dies auch ohne Umwandlung geht.
Das "wie" und "ob" das möglich ist hat mich dabei schlicht und ergreifend interessiert.

Liebe Grüße

Bill
Athomas
Beiträge: 769
Registriert: Mo Feb 26, 2018 8:19 pm

Re: elementweises Dividieren zweier Listen

Beitrag von Athomas »

Warum zwei Listen in eine andere Datenstruktur umwandeln um eine simple mathematische Operation auszuführen, wenn dies auch ohne Umwandlung geht.
Na jut, in meinen Augen schreien diese beiden Vektoren geradezu danach, von Ihrem lustigen Listenkostüm befreit zu werden...
Wie sie da wohl reingekommen sind?
bigben
Beiträge: 2777
Registriert: Mi Okt 12, 2016 9:09 am

Re: elementweises Dividieren zweier Listen

Beitrag von bigben »

Hallo Bill,

natürlich sind Fragen wie Deine hier sehr willkommen. Da Du ja nun genügend Antworten hast und weil wir wissen, dass Du dich erst in R einfindest, darf man auch so antworten : Wenn Du zwei gleichlange Listen mit nur Zahlen hast und Element i in der einen gehört zu Element i in der anderen Liste, dann stecken die Daten in der falschen Struktur. Dann gehören sie in einen Dataframe.

LG, Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: elementweises Dividieren zweier Listen

Beitrag von EDi »

Bei 3 Elementen sieht's so aus:

Code: Alles auswählen

Unit: microseconds
                                                           expr     min       lq      mean   median       uq      max
                  mapply("/", Liste1, Liste2, SIMPLIFY = FALSE)  10.339  12.8235  16.10615  15.5165  18.9655   30.145
                            purrr::map2(Liste1, Liste2, ~.x/.y)  58.776  66.6240  85.38974  73.3450  80.2800  961.865
                               purrr::map2(Liste1, Liste2, `/`) 205.388 214.8120 231.28585 220.3765 226.7890  609.716
 lapply(seq_along(Liste1), function(i) Liste1[[i]]/Liste2[[i]])   5.880   7.9625  32.81723   9.9805  12.2835 2259.677
                                 base::Map(`/`, Liste1, Liste2)  16.342  20.0985  24.15535  23.8940  27.2135   55.985
                                  unlist(Liste1)/unlist(Liste2)   2.415   3.2865   4.33557   4.4265   5.0595   17.032
 neval cld
   100 a  
   100  b 
   100   c
   100 a  
   100 a  
   100 a  
bei 10000 Elementen wird's nochmal interessanter:

Code: Alles auswählen

Unit: microseconds
                                                           expr       min        lq       mean     median         uq
                  mapply("/", Liste1, Liste2, SIMPLIFY = FALSE)  8087.970  8339.389  9569.1413  8558.3505  9563.3330
                            purrr::map2(Liste1, Liste2, ~.x/.y) 16600.885 17576.513 19435.5000 18126.2055 20079.1660
                               purrr::map2(Liste1, Liste2, `/`) 28151.275 29576.637 32550.6149 30340.2145 33483.4175
 lapply(seq_along(Liste1), function(i) Liste1[[i]]/Liste2[[i]])  9194.445  9652.489 10589.1585  9921.2150 10319.3295
                                 base::Map(`/`, Liste1, Liste2)  8139.304  8371.267 10146.8087  8634.5985  9268.1770
                                  unlist(Liste1)/unlist(Liste2)   488.879   602.071   663.8463   614.4915   684.0695
       max neval  cld
 19506.528   100  b  
 30508.655   100   c 
 62777.701   100    d
 19927.844   100  b  
 38859.516   100  b  
  1203.355   100 a
Umwandels ist also ~15x schneller, als das zweitschnellste mapply().
Map() ist langsamer also mapply, vermutlich wegen dem wrapper overhead.
lapply() ist ähnlich schnell zu Map.

purrr ist wie zu erwarten (fokus liegt nicht auf schnelligkeit, denn auf konsistenz) langsamer. Erstaunt hat mich, dass die anonyme funktion schneller war, als den Operator zu übergeben (muss vielleicht noch danach suchen im Pfad?).

Eigenltich gibt es keinen Grund hier nicht umzuwandeln und eigentlich ist eine Liste die falsche Datenstruktur für das Problem.

Code: Alles auswählen

R> sessionInfo()
R version 4.0.0 (2020-04-24)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Arch Linux

Matrix products: default
BLAS:   /usr/lib/libopenblasp-r0.3.9.so
LAPACK: /usr/lib/liblapack.so.3.9.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
[1] microbenchmark_1.4-7 dplyr_0.8.5          shinyWidgets_0.5.1   shiny_1.4.0.2       

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6     compiler_4.0.0   pillar_1.4.3     later_1.0.0      tools_4.0.0      digest_0.6.25    jsonlite_1.6.1  
 [8] lifecycle_0.2.0  tibble_3.0.1     lattice_0.20-41  pkgconfig_2.0.3  rlang_0.4.5      Matrix_1.2-18    rstudioapi_0.11 
[15] mvtnorm_1.1-0    fastmap_1.0.1    vctrs_0.2.4      grid_4.0.0       tidyselect_1.0.0 glue_1.4.0       R6_2.4.1        
[22] survival_3.1-12  multcomp_1.4-13  TH.data_1.0-10   purrr_0.3.4      magrittr_1.5     codetools_0.2-16 MASS_7.3-51.6   
[29] splines_4.0.0    scales_1.1.0     promises_1.1.0   htmltools_0.4.0  ellipsis_0.3.0   rsconnect_0.8.16 assertthat_0.2.1
[36] mime_0.9         xtable_1.8-4     colorspace_1.4-1 httpuv_1.5.2     sandwich_2.5-1   munsell_0.5.0    crayon_1.3.4    
[43] Cairo_1.5-12     zoo_1.8-7  
Lief auf einem kleinen Dell XPS 13 (Intel Core i5-6200u 2,30Ghz), ca 3.5 Jahre alt.
Dividiert wurde nur ganze Zahlen:

Code: Alles auswählen

n <- 10000
Liste1 <- as.list(rpois(n, 20))
Liste2 <- as.list(rpois(n, 20))
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.
Bill
Beiträge: 35
Registriert: Fr Mär 06, 2020 8:04 pm

Re: elementweises Dividieren zweier Listen

Beitrag von Bill »

Hallo Leute,

dass in meinem Beispiel die Liste nicht die passende Datenstruktur ist, wie ihr meintet, leuchtet mir ein.

Tolle Auswertungen!
Interessant dass das Umwandeln die Nase vorn hat, wenn es um Zeit geht und die Silbermedaille so an mapply() geht.

In puncto Eleganz (Schönheit) spricht mich persönlich jedoch die Map() Variante am Meisten an, aber das nur am Rande.


Liebe Grüße

Bill
Antworten