Zasadniczo możesz zrobić prawie wszystko w Shiny, ponieważ możesz tworzyć własne wiązania i output, więc odpowiedź na twoje pytanie brzmi "tak", to, o co prosisz, jest możliwe. Załóżmy, że masz ramkę danych, którą wysyłasz na stronę internetową, którą chcesz przeglądać. Na przykład, pozwól użytkownikom po prostu kliknąć komórkę, jeśli jest to usunięcie, które powinno zostać usunięte (zastąpione NA
).
Powiedzmy ramka danych wygląda następująco:
x <- data.frame(Age = c(10, 20, 1000), Weight = c(120, 131, 111))
x
# Age Weight
# 10 120
# 20 131
# 1000 111
Od błyszczące byś zbudować normalną tabelę HTML, który może wyglądać mniej więcej tak, gdy wyświetlany na stronie:
<table class="outlier-finder" id="outliers">
<tr>
<td>Age</td>
<td>Weight</td>
</tr>
<tr>
<td>10</td>
<td>120</td>
</tr>
<tr>
<td>20</td>
<td>131</td>
</tr>
<tr>
<td>1000</td>
<td>111</td>
</tr>
</table>
Teraz przełamania out jQuery i wiązać zdarzenie click tak, że po kliknięciu komórki można nagrać numer wiersza i kolumny (see here), a następnie zastąpić tę komórkę NA
w Shiny. Twój wkład wiążący może wyglądać mniej więcej tak (see here for details of what's going on here):
$(document).on("click", ".outlier-finder td", function(evt) {
// Identify the clicked cell.
var el = $(evt.target);
// Raise an event to signal that the something has been selected.
el.trigger("change");
});
var cell_binding = new Shiny.InputBinding();
$.extend(cell_binding, {
find: function(scope) {
return $(scope).find(".outlier-finder td");
},
getValue: function(el) {
// Get the row and cell number of the selected td.
var col = el.parent().children().index(el);
var row = el.parent().parent().children().index(el.parent());
var result = [row, col];
return result;
},
setValue: function(el, value) {
$(el).text(value);
},
subscribe: function(el, callback) {
$(el).on("change.cell_binding", function(e) {
callback();
});
},
unsubscribe: function(el) {
$(el).off(".cell_binding");
}
});
Shiny.inputBindings.register(cell_binding);
Dużo się tu dzieje, ale generalnie te powiązania wejściowe są dość podobne do siebie. Najważniejszą rzeczą jest funkcja setValue()
. Co powinno się tam dziać (to nie jest testowane) to numer wiersza i kolumny klikniętej komórki jest rejestrowany i przesyłany z powrotem do serwera.
Następnie z Shiny byś po prostu zrobić coś takiego:
updateData <- reactive({
# Get selection
remove_outlier <- as.integer(RJSONIO::fromJSON(input$outliers))
if (!is.null(remove_outlier)) {
# Remove that outlier.
x[remove_outlier[1], remove_outlier[2]] <- NA
}
return(x)
})
output$outliers <- renderText({
# Update x.
current_x <- updateData()
# Write code to output current_x to page.
# ...
# ...
})
Prawdopodobnie będzie trzeba dokonać moc wiążącą dla wyjściowych $ skrajnych, jak również. To jest uproszczony kod tutaj oczywiście, musisz zastosować sprawdzanie błędów itp.
To tylko przykład. W rzeczywistości, prawdopodobnie nie będziesz miał Błyszczącej aktualizacji ramek danych za każdym razem, gdy użytkownik wprowadzi zmianę. Będziesz chciał mieć jakiś przycisk przesyłania, aby po wprowadzeniu przez użytkownika wszystkich zmian można było zastosować.
nie mam nawet zdalnie badane któregokolwiek z tym więc są prawie na pewno jakieś błędy. Ale skoro tylko zadałeś teoretyczne pytanie, nie sprawdziłem tego zbyt wiele.Ogólna taktyka powinna i tak zadziałać. Dzięki powiązaniom wejściowym można uzyskać wszystko, od strony WWW z powrotem do serwera i odwrotnie, z powiązaniami wyjściowymi. Może powiedzenie "coś" jest rozciągliwe —, ale możesz zrobić dużo.
Domyślam się, że trudnością jest posiadanie edytowalnej tabeli danych, nie znam istniejącej. Informacje mogą wrócić do serwera, gdy mamy taką wyświetlaną i edytowalną tabelę danych. – Zhenglei