Interpolation von Influenza-Daten, die den Wochenmittelwert erhalten


13

Bearbeiten

Ich habe ein Dokument gefunden , das genau das beschreibt, was ich brauche. Der einzige Unterschied besteht darin, dass das Papier die Monatsmittelwerte in Tagesdaten interpoliert, während die Monatsmittelwerte beibehalten werden. Ich habe Probleme, den Ansatz zu implementieren R. Hinweise sind willkommen.

Original

Für jede Woche liegen mir folgende Zähldaten vor (ein Wert pro Woche):

  • Anzahl der Arztkonsultationen
  • Anzahl der Fälle von Influenza

Mein Ziel ist es, tägliche Daten durch Interpolation zu erhalten (ich dachte an lineare oder abgeschnittene Splines). Das Wichtige ist, dass ich den Wochenmittelwert beibehalten möchte , dh der Mittelwert der täglich interpolierten Daten sollte dem aufgezeichneten Wert dieser Woche entsprechen. Außerdem sollte die Interpolation glatt sein. Ein Problem, das auftreten kann, ist, dass eine bestimmte Woche weniger als 7 Tage hat (z. B. am Anfang oder Ende eines Jahres).

Ich wäre für Ratschläge in dieser Angelegenheit dankbar.

Danke vielmals.

Hier ist ein Beispieldatensatz für das Jahr 1995 ( aktualisiert ):

structure(list(daily.ts = structure(c(9131, 9132, 9133, 9134, 
9135, 9136, 9137, 9138, 9139, 9140, 9141, 9142, 9143, 9144, 9145, 
9146, 9147, 9148, 9149, 9150, 9151, 9152, 9153, 9154, 9155, 9156, 
9157, 9158, 9159, 9160, 9161, 9162, 9163, 9164, 9165, 9166, 9167, 
9168, 9169, 9170, 9171, 9172, 9173, 9174, 9175, 9176, 9177, 9178, 
9179, 9180, 9181, 9182, 9183, 9184, 9185, 9186, 9187, 9188, 9189, 
9190, 9191, 9192, 9193, 9194, 9195, 9196, 9197, 9198, 9199, 9200, 
9201, 9202, 9203, 9204, 9205, 9206, 9207, 9208, 9209, 9210, 9211, 
9212, 9213, 9214, 9215, 9216, 9217, 9218, 9219, 9220, 9221, 9222, 
9223, 9224, 9225, 9226, 9227, 9228, 9229, 9230, 9231, 9232, 9233, 
9234, 9235, 9236, 9237, 9238, 9239, 9240, 9241, 9242, 9243, 9244, 
9245, 9246, 9247, 9248, 9249, 9250, 9251, 9252, 9253, 9254, 9255, 
9256, 9257, 9258, 9259, 9260, 9261, 9262, 9263, 9264, 9265, 9266, 
9267, 9268, 9269, 9270, 9271, 9272, 9273, 9274, 9275, 9276, 9277, 
9278, 9279, 9280, 9281, 9282, 9283, 9284, 9285, 9286, 9287, 9288, 
9289, 9290, 9291, 9292, 9293, 9294, 9295, 9296, 9297, 9298, 9299, 
9300, 9301, 9302, 9303, 9304, 9305, 9306, 9307, 9308, 9309, 9310, 
9311, 9312, 9313, 9314, 9315, 9316, 9317, 9318, 9319, 9320, 9321, 
9322, 9323, 9324, 9325, 9326, 9327, 9328, 9329, 9330, 9331, 9332, 
9333, 9334, 9335, 9336, 9337, 9338, 9339, 9340, 9341, 9342, 9343, 
9344, 9345, 9346, 9347, 9348, 9349, 9350, 9351, 9352, 9353, 9354, 
9355, 9356, 9357, 9358, 9359, 9360, 9361, 9362, 9363, 9364, 9365, 
9366, 9367, 9368, 9369, 9370, 9371, 9372, 9373, 9374, 9375, 9376, 
9377, 9378, 9379, 9380, 9381, 9382, 9383, 9384, 9385, 9386, 9387, 
9388, 9389, 9390, 9391, 9392, 9393, 9394, 9395, 9396, 9397, 9398, 
9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 
9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, 
9421, 9422, 9423, 9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 
9432, 9433, 9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441, 9442, 
9443, 9444, 9445, 9446, 9447, 9448, 9449, 9450, 9451, 9452, 9453, 
9454, 9455, 9456, 9457, 9458, 9459, 9460, 9461, 9462, 9463, 9464, 
9465, 9466, 9467, 9468, 9469, 9470, 9471, 9472, 9473, 9474, 9475, 
9476, 9477, 9478, 9479, 9480, 9481, 9482, 9483, 9484, 9485, 9486, 
9487, 9488, 9489, 9490, 9491, 9492, 9493, 9494, 9495), class = "Date"), 
    wdayno = c(0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 
    5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 
    6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 
    0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 
    1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 
    2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 
    3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 
    4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 
    5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 
    6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 
    0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 
    1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 
    2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 
    3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 
    4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 
    5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 
    6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 
    0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 
    1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 
    2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 
    3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 
    4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 
    5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 
    6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 
    0L, 1L, 2L, 3L, 4L, 5L, 6L, 0L), month = c(1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
    4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
    6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 
    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 
    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 
    9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 
    10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 
    11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 
    12, 12, 12, 12), year = c(1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 
    1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995), yearday = 0:364, 
    no.influ.cases = c(NA, NA, NA, 168L, NA, NA, NA, NA, NA, 
    NA, 199L, NA, NA, NA, NA, NA, NA, 214L, NA, NA, NA, NA, NA, 
    NA, 230L, NA, NA, NA, NA, NA, NA, 267L, NA, NA, NA, NA, NA, 
    NA, 373L, NA, NA, NA, NA, NA, NA, 387L, NA, NA, NA, NA, NA, 
    NA, 443L, NA, NA, NA, NA, NA, NA, 579L, NA, NA, NA, NA, NA, 
    NA, 821L, NA, NA, NA, NA, NA, NA, 1229L, NA, NA, NA, NA, 
    NA, NA, 1014L, NA, NA, NA, NA, NA, NA, 831L, NA, NA, NA, 
    NA, NA, NA, 648L, NA, NA, NA, NA, NA, NA, 257L, NA, NA, NA, 
    NA, NA, NA, 203L, NA, NA, NA, NA, NA, NA, 137L, NA, NA, NA, 
    NA, NA, NA, 78L, NA, NA, NA, NA, NA, NA, 82L, NA, NA, NA, 
    NA, NA, NA, 69L, NA, NA, NA, NA, NA, NA, 45L, NA, NA, NA, 
    NA, NA, NA, 51L, NA, NA, NA, NA, NA, NA, 45L, NA, NA, NA, 
    NA, NA, NA, 63L, NA, NA, NA, NA, NA, NA, 55L, NA, NA, NA, 
    NA, NA, NA, 54L, NA, NA, NA, NA, NA, NA, 52L, NA, NA, NA, 
    NA, NA, NA, 27L, NA, NA, NA, NA, NA, NA, 24L, NA, NA, NA, 
    NA, NA, NA, 12L, NA, NA, NA, NA, NA, NA, 10L, NA, NA, NA, 
    NA, NA, NA, 22L, NA, NA, NA, NA, NA, NA, 42L, NA, NA, NA, 
    NA, NA, NA, 32L, NA, NA, NA, NA, NA, NA, 52L, NA, NA, NA, 
    NA, NA, NA, 82L, NA, NA, NA, NA, NA, NA, 95L, NA, NA, NA, 
    NA, NA, NA, 91L, NA, NA, NA, NA, NA, NA, 104L, NA, NA, NA, 
    NA, NA, NA, 143L, NA, NA, NA, NA, NA, NA, 114L, NA, NA, NA, 
    NA, NA, NA, 100L, NA, NA, NA, NA, NA, NA, 83L, NA, NA, NA, 
    NA, NA, NA, 113L, NA, NA, NA, NA, NA, NA, 145L, NA, NA, NA, 
    NA, NA, NA, 175L, NA, NA, NA, NA, NA, NA, 222L, NA, NA, NA, 
    NA, NA, NA, 258L, NA, NA, NA, NA, NA, NA, 384L, NA, NA, NA, 
    NA, NA, NA, 755L, NA, NA, NA, NA, NA, NA, 976L, NA, NA, NA, 
    NA, NA, NA, 879L, NA, NA, NA, NA), no.consultations = c(NA, 
    NA, NA, 15093L, NA, NA, NA, NA, NA, NA, 20336L, NA, NA, NA, 
    NA, NA, NA, 20777L, NA, NA, NA, NA, NA, NA, 21108L, NA, NA, 
    NA, NA, NA, NA, 20967L, NA, NA, NA, NA, NA, NA, 20753L, NA, 
    NA, NA, NA, NA, NA, 18782L, NA, NA, NA, NA, NA, NA, 19778L, 
    NA, NA, NA, NA, NA, NA, 19223L, NA, NA, NA, NA, NA, NA, 21188L, 
    NA, NA, NA, NA, NA, NA, 22172L, NA, NA, NA, NA, NA, NA, 21965L, 
    NA, NA, NA, NA, NA, NA, 21768L, NA, NA, NA, NA, NA, NA, 21277L, 
    NA, NA, NA, NA, NA, NA, 16383L, NA, NA, NA, NA, NA, NA, 15337L, 
    NA, NA, NA, NA, NA, NA, 19179L, NA, NA, NA, NA, NA, NA, 18705L, 
    NA, NA, NA, NA, NA, NA, 19623L, NA, NA, NA, NA, NA, NA, 19363L, 
    NA, NA, NA, NA, NA, NA, 16257L, NA, NA, NA, NA, NA, NA, 19219L, 
    NA, NA, NA, NA, NA, NA, 17048L, NA, NA, NA, NA, NA, NA, 19231L, 
    NA, NA, NA, NA, NA, NA, 20023L, NA, NA, NA, NA, NA, NA, 19331L, 
    NA, NA, NA, NA, NA, NA, 18995L, NA, NA, NA, NA, NA, NA, 16571L, 
    NA, NA, NA, NA, NA, NA, 15010L, NA, NA, NA, NA, NA, NA, 13714L, 
    NA, NA, NA, NA, NA, NA, 10451L, NA, NA, NA, NA, NA, NA, 14216L, 
    NA, NA, NA, NA, NA, NA, 16800L, NA, NA, NA, NA, NA, NA, 18305L, 
    NA, NA, NA, NA, NA, NA, 18911L, NA, NA, NA, NA, NA, NA, 17812L, 
    NA, NA, NA, NA, NA, NA, 18665L, NA, NA, NA, NA, NA, NA, 18977L, 
    NA, NA, NA, NA, NA, NA, 19512L, NA, NA, NA, NA, NA, NA, 17424L, 
    NA, NA, NA, NA, NA, NA, 14464L, NA, NA, NA, NA, NA, NA, 16383L, 
    NA, NA, NA, NA, NA, NA, 19916L, NA, NA, NA, NA, NA, NA, 18255L, 
    NA, NA, NA, NA, NA, NA, 20113L, NA, NA, NA, NA, NA, NA, 20084L, 
    NA, NA, NA, NA, NA, NA, 20196L, NA, NA, NA, NA, NA, NA, 20184L, 
    NA, NA, NA, NA, NA, NA, 20261L, NA, NA, NA, NA, NA, NA, 22246L, 
    NA, NA, NA, NA, NA, NA, 23030L, NA, NA, NA, NA, NA, NA, 10487L, 
    NA, NA, NA, NA)), .Names = c("daily.ts", "wdayno", "month", 
"year", "yearday", "no.influ.cases", "no.consultations"), row.names = c(NA, 
-365L), class = "data.frame")

4
Diese Frage erfordert eine eindimensionale Version der Flächen-zu-Punkt-Interpolation , die im Bergbau ziemlich gut untersucht ist. In der referenzierten Zusammenfassung wird ausdrücklich darauf hingewiesen, dass geostatistische Methoden "kohärente (massenerhaltende ...) Vorhersagen" liefern. Ich glaube, diese Ansätze überwinden die Einwände von @Nick Cox.
Whuber

@whuber Danke für den Hinweis, ich wusste nicht, dass diese Art von Problem in der Geostatistik bekannt ist. Ist Ihnen eine Implementierung solcher Methoden in Roder in anderen Statistikpaketen bekannt (ich habe keinen Zugriff auf ArcGIS)? Ohne eine konkret verfügbare Implementierung stecke ich leider immer noch fest.
COOLSerdash

2
Ich glaube, dies könnte mit dem Code in geschehen geoRglm, vorausgesetzt, Sie haben ein sehr gutes Verständnis für Variographie und Änderung der Unterstützung (die für die Entwicklung des räumlichen Korrelationsmodells erforderlich ist). Das Handbuch erscheint im Springer Verlag als Modellbasierte Geostatistik, Diggle & Ribeiro Jr.
whuber

3
Die Unterteilung gruppierter Daten ist in der Demografie ein weit verbreitetes Verfahren. Ein Suchbegriff ist "Sprague-Interpolation"; es wird Sie zu vielen Variationen führen. Durch Anpassen eines Splines fünften Grades an die kumulativen Werte auf eine Weise, die eine monotone Kurve sicherstellt, teilen diese Methode und ihre Varianten gruppierte Daten effektiv neu auf. (Es gibt es schon seit 1880.) Der Oberbegriff ist "oszillatorische Interpolation". Rob Hyndman hat unter anderem zu diesem Thema geschrieben: Siehe Smith, Hyndman und Wood, Spline-Interpolation für demografische Variablen: Das Monotonie-Problem, J. Pop. Res. 21 No. 1 (2004), 95 & ndash; 98.
Whuber

2
Ihre Frage kann auch als dasymetrisches Mapping in einer Dimension betrachtet werden. Dies ist ein Verfahren zum Erstellen detaillierter Karten von Mengen, die auf einer bestimmten aggregierten Ebene gemessen wurden, z. B. Standardzählereinheiten. (Es kann mindestens bis 1936 zurückverfolgt werden: siehe John K. Wright, Eine Methode zur Kartierung der Bevölkerungsdichte: Am Beispiel von Cape Cod. Geographical Review 26: 1 (Januar 1936), S. 103-110.) Für a jüngster Ansatz (etwas ad hoc , aber mit einer kurzen hilfreichen Bibliographie) siehe giscience.org/proceedings/abstracts/giscience2012_paper_179.pdf .
Whuber

Antworten:


8

Es ist mir gelungen, eine RFunktion zu erstellen , die Punkte mit gleichmäßigem Abstand linear und mit Splines interpoliert, wobei die Mittelwerte (z. B. wöchentlich, monatlich usw.) erhalten bleiben. Es verwendet die Funktionen na.approxund na.splineaus dem zooPaket und berechnet iterativ die Splines mit den gewünschten Eigenschaften. Der Algorithmus wird in diesem Artikel beschrieben .

Hier ist der Code:

interpol.consmean <- function(y, period=7, max.iter=100, tol=1e-4, plot=FALSE) {

  require(zoo)

  if( plot == TRUE ) {
    require(ggplot2)
  }

  y.temp.linear <- matrix(NA, ncol=length(y), nrow=max.iter+1)
  y.temp.linear[1, ] <- y

  y.temp.spline <- y.temp.linear

  y.temp.pred.spline <- matrix(NA, ncol=length(y), nrow=max.iter)
  y.temp.pred.linear <- matrix(NA, ncol=length(y), nrow=max.iter)

  ind.actual <- which(!is.na(y))

  if ( !all(diff(ind.actual)[1]== diff(ind.actual)) ) {
    stop("\"y\" must contain an evenly spaced time series")
  }

  partial <- ifelse((length(y) - ind.actual[length(ind.actual)]) < period/2,
                    TRUE, FALSE)

  for(k in 1:max.iter) {

    y.temp.pred.linear[k,] <- na.approx(y.temp.linear[k, ], na.rm=FALSE, rule=2)
    y.temp.pred.spline[k,] <- na.spline(y.temp.spline[k, ], method="fmm")

    interpol.means.linear <- rollapply(y.temp.pred.linear[k,], width=period, mean,
                                       by=period, align="left", partial=partial) 
    interpol.means.splines <- rollapply(y.temp.pred.spline[k,], width=period, mean,
                                        by=period, align="left", partial=partial) 

    resid.linear <- y.temp.linear[k, ][ ind.actual ] - interpol.means.linear
    resid.spline <- y.temp.spline[k, ][ ind.actual ] - interpol.means.splines

    if ( max(resid.linear, na.rm=TRUE) < tol & max(resid.spline, na.rm=TRUE) < tol ){
      cat("Converged after", k, "iterations with tolerance of", tol, sep=" ")
      break
    }

    y.temp.linear[k+1, ][!is.na(y.temp.linear[k, ])] <-  resid.linear
    y.temp.spline[k+1, ][!is.na(y.temp.spline[k, ])] <-  resid.spline

  }  

  interpol.linear.final <- colSums(y.temp.pred.linear, na.rm=TRUE)
  interpol.spline.final <- colSums(y.temp.pred.spline, na.rm=TRUE)

  if ( plot == TRUE ) {

    plot.frame <- data.frame(
      y=rep(y,2)/7,
      x=rep(1:length(y),2),
      inter.values=c(interpol.linear.final, interpol.spline.final)/7,
      method=c(rep("Linear", length(y)), rep("Spline", length(y)))
    )

    p <- ggplot(data=plot.frame, aes(x=x)) +
      geom_point(aes(y=y, x=x), size=4) +
      geom_line(aes(y=inter.values, color=method), size=1) +
      ylab("y") +
      xlab("x") +
      theme(axis.title.y =element_text(vjust=0.4, size=20, angle=90)) +
      theme(axis.title.x =element_text(vjust=0, size=20, angle=0)) +
      theme(axis.text.x =element_text(size=15, colour = "black")) +
      theme(axis.text.y =element_text(size=17, colour = "black")) +
      theme(panel.background =  element_rect(fill = "grey85", colour = NA),
            panel.grid.major =  element_line(colour = "white"),
            panel.grid.minor =  element_line(colour = "grey90", size = 0.25))+
      scale_color_manual(values=c("#377EB8", "#E41A1C"), 
                         name="Interpolation method",
                         breaks=c("Linear", "Spline"),
                         labels=c("Linear", "Spline")) +
      theme(legend.position="none") +
      theme(strip.text.x = element_text(size=16)) +
      facet_wrap(~ method)

    suppressWarnings(print(p))

  }
  list(linear=interpol.linear.final, spline=interpol.spline.final)
}

Wenden wir die Funktion auf den in der Frage angegebenen Beispieldatensatz an:

interpolations <- interpol.consmean(y=dat.frame$no.influ.cases, period=7,
                                    max.iter = 100, tol=1e-6, plot=TRUE)

Interpolationen

Sowohl die lineare als auch die Spline-Interpolation scheinen in Ordnung zu sein. Lassen Sie uns überprüfen, ob die wöchentlichen Mittelwerte erhalten bleiben (abgeschnittene Ausgabe):

cbind(dat.frame$no.influ.cases[!is.na(dat.frame$no.influ.cases)],
      rollapply(interpolations$linear, 7, mean, by=7, align="left", partial=F))

      [,1] [,2]
 [1,]  168  168
 [2,]  199  199
 [3,]  214  214
 [4,]  230  230
 [5,]  267  267
 [6,]  373  373
 [7,]  387  387
 [8,]  443  443
 [9,]  579  579
[10,]  821  821
[11,] 1229 1229

1
Sie sollten ein passendes Paket dafür finden und den Betreuer fragen, ob er es einbinden möchte.
Spacedman

4

Jede gerade Linie, die den Mittelwert in der Mitte des Bereichs durchläuft, erzeugt Tageswerte mit dem erforderlichen Mittelwert. Nick Cox 'letzter Kommentar zur Division der wöchentlichen Zählungen durch die Anzahl der Tage' ist ein Sonderfall mit einem Gradienten von 0.

Also können wir dies anpassen und den Verlauf wählen, um die Dinge vielleicht etwas ruhiger zu machen. Hier sind drei R-Funktionen, um so etwas zu tun:

interpwk <- function(x,y,delta){
  offset=-3:3
  yout=y+delta*offset
  xout=x+offset
  cbind(xout,yout)
}

get_delta <- function(x,y,pos){
  (y[pos+1]-y[pos-1])/(x[pos+1]-x[pos-1])
}

#' get slope from neighbours
interpall <- function(x,y,delta1,f=1){
  for(i in 2:(length(x)-1)){
    delta=get_delta(x,y,i)
    xyout=interpwk(x[i],y[i],delta/f)
    points(xyout)
  }
}

Fügen Sie Ihren Daten ein Tagesmaß hinzu, zeichnen Sie dann und zeichnen Sie dann den Interpolator:

> data$day=data$week*7
> plot(data$day,data$no.influ.cases,type="l")
> interpall(data$day,data$no.influ.cases,f=1)

linearer mittelwerterhaltender Interpolator

Eine andere Möglichkeit besteht darin, die Kontinuität an Wochenenden zu beschränken, aber dies gibt Ihnen ein System mit nur einem Freiheitsgrad - dh es wird vollständig durch die Neigung des ersten Abschnitts definiert (da sich dann alle anderen Abschnitte verbinden müssen). Ich habe das nicht codiert - Sie haben eine Chance!

[Apols für den etwas schäbigen R-Code, es sollte wirklich die Punkte zurückgeben, anstatt sie zu zeichnen]


+1, danke. Das Problem ist, dass die interpolierten Werte nicht glatt sind und es zwischen den Wochen ziemlich abrupte Schritte gibt. Ich habe meine Frage einschließlich eines Papiers bearbeitet, das im Grunde genau den Ansatz erklärt, den ich brauche.
COOLSerdash

Was ist der Zweck hier? Warum vermuten Influenza-Fälle variieren reibungslos? Je mehr Struktur Sie durch Interpolation in diese Daten einfügen, desto mehr muss die eingeführte Struktur in einem Modellierungsstadium nur entwirrt werden. Ich glaube nicht, dass Sie meinen Kommentar vom 19. Mai angesprochen haben. "Das Aufblähen von wöchentlichen Daten auf tägliche Daten führt nur zu Problemen mit der eingeführten Abhängigkeit und wild zu optimistischen Freiheitsgraden, die die Anpassung und Bewertung von Modellen beeinträchtigen."
Nick Cox

Das Beschränken auf den Mittelwert ist jedoch falsch. Der hier angezeigte Mittelwert ist ein Beispielmittelwert und unterliegt in irgendeiner Weise statistischen Schwankungen. Zaubere ein Modell, verwende dann einen Interpolator, der den Mittelwert als Erwartung hat, führe dann mehrere Imputationen der täglichen Daten durch und analysiere sie mindestens hundert Mal, um herauszufinden, wie sich diese Unsicherheit auf deine Schlussfolgerungen auswirkt.
Spacedman

1
@Spacedman Die geostatistischen API-Methoden, auf die ich (in einem Kommentar zur Frage) verwiesen habe, behandeln Ihren (durchaus gültigen) Einwand mit Gelassenheit mithilfe einer Nicht-Null-Komponente im Variogramm-Nugget-Parameter. Geostatistische bedingte Simulationen sind eine kontrollierte Methode zur Durchführung der von Ihnen genannten Mehrfachzuschreibungen.
Whuber

2
Absolut. Sie scheinen eine eindimensionale Situation zu haben, die fast genau dem Beispiel im Diggle & Ribeiro-Handbuch für geoRglm entspricht (Malariafälle in Gambia, mit Nähe zu Sümpfen usw. als Kovariaten). Die Hauptkomplikation ist die Handhabung der Änderung der Unterstützung, aber das würde die Vorhersage nicht wirklich beeinflussen: Es würde hauptsächlich die Schätzung des Variogramms beeinflussen. In ncbi.nlm.nih.gov/pmc/articles/PMC2995922 finden Sie einige theoretische und ähnliche Beispiele ("binomiales Kriging" von Krankheitsfällen).
Whuber

3

n

(Wenn es sich bei den Daten eher um Messungen als um Zählungen gehandelt hätte, würde ich eher die Proportionen über ein Dirichlet-Modell modellieren, aber das ist etwas komplizierter.)

Die Tatsache, dass die Anzahl der Tage nicht immer gleich sein wird, sollte kein besonderes Problem sein, solange Sie wissen, was es ist - solange Sie einen Versatz verwenden, um die Dinge auf das gleiche "Niveau" zu bringen.


1
Korrigiere mich, wenn ich falsch liege, aber ich denke, das hat die Frage nach hinten. Es ist nicht so, wie man die täglichen Zählungen glättet. So erraten Sie die täglichen Zählungen anhand der wöchentlichen Daten. (Vermutlich enthält das Poster tägliche Daten für etwas anderes, z. B. Temperaturen.) Abgesehen davon, wie ist dieses Multinom oder Dirichlet? Sieht für mich eher nach einem Poisson aus.
Nick Cox

@NickCox Sie haben absolut recht, danke für die Klarstellung: Ich habe wöchentliche Daten und möchte tägliche Daten, weil ich andere Daten habe, die täglich vorliegen (dh meteorologische Variablen, Sterblichkeit, Luftverschmutzung usw.).
COOLSerdash

3
Meine eigene Meinung zu dieser Frage ist, warum Sie dies tun möchten. Ich vermute, wie oben, dass Sie einige tägliche Daten haben und alles auf der gleichen Basis wollen. In diesem Fall sollten Sie die täglichen Daten auf den Mindest-, Mittel-, Mittel- und Höchstwert über Wochen reduzieren oder was auch immer wissenschaftlich sinnvoll ist. Das Aufblähen von wöchentlichen Daten zu täglichen Daten führt nur zu Problemen mit der eingeführten Abhängigkeit und den zu optimistischen Freiheitsgraden, die die Anpassung und Bewertung von Modellen beeinträchtigen.
Nick Cox

@ Nick Cox es ist absolut "Vermutung", aber nach den gegebenen Informationen scheint das zu sein, was der OP wollte.
Glen_b

2
Ein weiterer konservativer Ansatz besteht darin, die wöchentlichen Zählungen durch die Anzahl der Tage zu dividieren. Ich weiß, dass es eine Voraussetzung dafür gibt, dass der eigentliche Prozess reibungsloser vonstatten geht, aber er wird den Mittelwert bewahren.
Nick Cox

3

Ich werde einige zusätzliche Kommentare zu einer weiteren Antwort zusammenfassen.

Es dauert eine Weile, bis die Struktur dieses Projekts klarer wird. Angesichts der Tatsache, dass die Influenza jetzt als eine Kovariate unter mehreren aufgedeckt wird, scheint es nicht so entscheidend zu sein, was Sie tun, oder zumindest nicht, um die in einigen meiner früheren Kommentare zum Ausdruck gebrachte Skepsis zu verdienen. Da alles andere tagtäglich ist, würden zu viele Details weggeworfen, wenn alles andere auf Wochen reduziert würde.

Der ursprüngliche Fokus der Frage bleibt auf der Interpolation, die den Wochenmittelwert beibehält, und auf die eine (extreme) Antwort lautet, dass der Wochenmittelwert den Wochenmittelwert beibehält. Da dies nicht überraschend unattraktiv oder unrealistisch erscheint, erscheinen andere Interpolationsmethoden attraktiver und / oder Imputationsmethoden, wie von @Spacedman vorgeschlagen. (Es ist mir nicht klar, ob dies eine Anrechnung mit einem zeitlichen Geschmack oder eine Interpolation mit einem zusätzlichen stochastischen Geschmack wäre.)

Zwei weitere spezifische Gedanken:

  • Wenn man die Wochenwerte (dividiert durch die Anzahl der Tage) nimmt und dann mit gewichteten Durchschnitten glättet, wird der Mittelwert in der Praxis wahrscheinlich in guter Näherung beibehalten.

  • Da es sich bei den Influenzafällen um Zählungen handelt, funktioniert das Glätten der Stamm- oder Protokollzählungen und anschließende Rücktransformation möglicherweise besser als nur das Glätten der Zählungen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.