2016-05-13 9 views
0

Ich versuche, die Zahlen in einem Währungsformat und dann runden sie, aber ich bekomme unerwartetes Verhalten von DT (V 0.1).Rundung Währung formatierte Zahlen in DT

Ich möchte die Werte wie 808084.227872401 in £808,084.2 suchen

Hier ist der Code:

library(DT) 

m <- structure(list(A = c(808084.227872401, 1968554.9592654, 751271.053745238, 
-248530.769710688, 1022891.09543523, -407303.626363765), B = c(143073.342325492, 
-1440469.87343229, -590080.736184761, -608299.78907882, 1167155.65688074, 
803870.898483576), C = c(-447086.9382469, 606572.488852836, 89371.3745637198, 
-1496047.6143101, -410103.544644035, 1106358.3287006), D = c(0.754009573487565, 
0.364774209912866, 0.525769896339625, 0.44853704655543, 0.909551323624328, 
0.439131782157347), E = c(98.8604132297185, 98.9055931760521, 
99.3795062166865, 98.5895350315005, 101.194549174315, 102.325111315431 
)), .Names = c("A", "B", "C", "D", "E"), row.names = c(NA, -6L 
), class = "data.frame") 

documentation Nach dieser Arbeit sollte:

datatable(m) %>% formatCurrency("A", "£", digits = 1) 

Aber ich erhalte den folgenden Fehler:

Error in formatCurrency(., "A", "£", digits = 1) : unused argument (digits = 1)

Dann habe ich versucht, einen anderen Befehl:

datatable(m) %>% formatCurrency("A", "£") %>% formatRound("A", 1) 

Aber es formatiert nur die Währung, ohne sie zu runden.

enter image description here

Irgendwelche Ideen?

PS. Ich bin mir bewusst, this Antwort, aber ich möchte keine Zeichenfolgen anzuzeigen, weil ich die Zahlen bei der Anzeige mit datatable sortieren möchten.

+1

Warum nicht regelmäßig "Runde" zuerst in dieser Spalte und dann Feed zu "Datatable"? – Gopala

+0

Ich möchte nicht die zugrunde liegenden Daten ändern, sondern nur die Art, wie sie angezeigt werden. Außerdem würde ich gerne wissen, was passiert, wenn ich DT benutze. – epo3

Antwort

1

Meine Schlussfolgerung ist, dass Sie nicht 2 Formatierer zu der gleichen Spalte mit DT hinzufügen können, obwohl ich natürlich falsch liegen könnte.

Beachten Sie, dass, selbst wenn dies nicht explizit in der Dokumentation DT angegeben ist, nur ein Formatierer pro Spaltentabelle hinzugefügt werden kann. Beachten Sie außerdem, dass die Beispiele in der von Ihnen angegebenen Verknüpfung oder bei der Eingabe von ?formatCurrency, wenn sie zwei Pipes %>% enthalten, immer auf zwei verschiedene Spalten wirken.

In Ihrem Beispiel, wenn Sie

tun
datatable(m) %>% formatRound("A", digits=1) %>% formatCurrency("A", currency="£") 

das Ergebnis Runde 1 Ziffer ohne Währung, und wenn Sie das tun

datatable(m) %>% formatCurrency("A", currency="£") %>% formatRound("A", digits=1) 

das Ergebnis ist die Währung ohne Rundung hinzugefügt.

Mein Wissen darüber, wie R mit js integriert sehr begrenzt ist, sondern an der R Quellen für the package in cran suchen, es sieht aus wie jeder Format-Befehl in dem Rohr anhängt einen Formatierer, aber aus irgendeinem Grunde nur eine Formatierer ins Spiel kommt:

formatCurrency = function(table, columns, currency = '$', interval = 3, mark = ',') { 
    formatColumns(table, columns, tplCurrency, currency, interval, mark) 
} 

formatRound = function(table, columns, digits = 2) { 
    formatColumns(table, columns, tplRound, digits) 
} 

formatColumns = function(table, columns, template, ...) { 
    ... 
    x$options$rowCallback = appendFormatter(
    x$options$rowCallback, columns, colnames, rownames, template, ... 
) 
    ... 
} 

appendFormatter = function(js, name, names, rownames = TRUE, template, ...) { 
    ... 
    JS(append(
    js, after = 1, 
    template(i, ...) 
)) 
} 

wo jeder Formatierer bis endet formatColumns mit einer anderen template Aufruf und i lösen eine ID für die Spalte. Wie gesagt, ich habe keine Ahnung, ob das daran liegt, dass die append-Operationen den Formatierer überschreiben, oder ob es mit der Ausführung zu tun hat.


EDIT: Sorry, ich versehentlich die Post-Taste gedrückt und bekam interruped. Ich habe tatsächlich einen Formatierer implementiert, der mehr Argumente benötigt.Die Lösung ist ein wenig verworren, aber es funktioniert. Dies ist ein Formatierer, der sowohl Währung und Ziffern akzeptiert:

tplRound2 = function(cols, currency, digits) { 
    sprintf(
    "var d = parseFloat(data[%d]); $(this.api().cell(row, %s).node()).html(isNaN(d) ? '' : '%s' + d.toFixed(%d).toString());", 
    cols, cols, currency, digits 
) 
} 

Sie müssen all diese Funktionen zu Ihrer Sitzung hinzuzufügen:

formatRound2 = function(table, columns, currency, digits = 2) { 
    formatColumns2(table, columns, tplRound2, currency, digits) 
} 

formatColumns2 = function(table, columns, template, ...) { 
    if (inherits(columns, 'formula')) columns = all.vars(columns) 
    x = table$x 
    colnames = base::attr(x, 'colnames', exact = TRUE) 
    rownames = base::attr(x, 'rownames', exact = TRUE) 
    x$options$rowCallback = appendFormatter2(
    x$options$rowCallback, columns, colnames, rownames, template, ... 
) 
    table$x = x 
    table 
} 

name2int = function(name, names) { 
    if (is.numeric(name)) { 
    return(if (all(name > 0)) name else seq_along(names)[name]) 
    } 
    names = setNames(seq_along(names), names) 
    unname(names[name]) 
} 

appendFormatter2 = function(js, name, names, rownames = TRUE, template, ...) { 
    js = if (length(js) == 0) c('function(row, data) {', '}') else { 
    unlist(strsplit(as.character(js), '\n')) 
    } 
    i = name2int(name, names) 
    if (is.character(name) || (is.numeric(name) && !rownames)) i = i - 1 
    if (any(is.na(i))) stop(
    'You specified the columns: ', paste(name, collapse = ', '), ', ', 
    'but the column names of the data are ', paste(names, collapse = ', ') 
) 
    JS(append(
    js, after = 1, 
    template(i, ...) 
)) 
} 

Und dann können Sie mit dem neuen Formatierungsprogramm führen Sie das gewünschte Ergebnis zu erhalten :

datatable(m) %>% formatRound2("A", "£", digits=1) 

(Allerdings bedeutet dies die , alle 3 Ziffern nicht hinzufügen, wenn Sie es wirklich brauchen ich es an den Formatierer hinzufügen könnte ...)


EDIT2 nach Kommentaren:

Dies wäre die Formafunktion für beide Währung und die Anzahl der Ziffern, sowie die ‚‘ Marken:

tplRound3 = function(cols, currency, digits, interval, mark) { 
    sprintf(
    "var d = parseFloat(data[%d]); $(this.api().cell(row, %s).node()).html(isNaN(d) ? '' : '%s' + d.toFixed(%d).toString().replace(/\\B(?=(\\d{%d})+(?!\\d))/g, '%s'));", 
    cols, cols, currency, digits, interval, mark 
) 
} 


formatRound3 = function(table, columns, currency, digits = 2, interval=3, mark=',') { 
    formatColumns2(table, columns, tplRound3, currency, digits, interval, mark) 
} 

Um es zu benutzen, Geben Sie einfach

datatable(m) %>% formatRound3("A", "£", digits=1) 
+0

Sorry @ epo3, versehentlich auf die Schaltfläche "Post" gedrückt, bearbeitet den Beitrag mit einer Art komplexer Lösung. – lrnzcig

+0

Große Antwort. Es wäre schön, wenn Sie alle 3 Ziffern ein Komma hinzufügen könnten. Das würde die Funktion vervollständigen. Ich denke, du könntest eine Verbesserung zu "DT" vorschlagen. Es wäre eine sehr nützliche Funktion, um dem Paket hinzuzufügen. – epo3

+1

Sie sind mehr als willkommen. Ich habe die Antwort mit dem Formatierer einschließlich Komma alle 3 Ziffern aktualisiert. Ja, vielleicht mache ich einen PR zu "DT". Vielen Dank. – lrnzcig