2017-01-07 6 views
-6

Ich habe einen Datenrahmen im langen Format mit einer Beobachtungszeile pro Messung. Ich möchte jede eindeutige ID durchlaufen und das "minimale" Datum für jede eindeutige Person finden. Zum Beispiel kann Patient 1 zu drei verschiedenen Zeiten gemessen werden, aber ich möchte den frühesten Zeitpunkt. Ich dachte daran, den Datensatz nach dem Datum zu sortieren (in aufsteigender Reihenfolge) und alle Duplikate zu entfernen, aber ich bin mir nicht sicher, ob dies der beste Weg ist. Jede Hilfe oder Vorschläge würde sehr geschätzt werden. Vielen Dank!Looping über eindeutige Werte

Antwort

1

Wir können data.table verwenden. Konvertieren Sie die ‚data.frame‘ auf ‚data.table‘ (setDT(df1)), gruppiert nach ‚ID‘, order das ‚Datum‘ (unter der Annahme, dass es in Date Klasse oder auch Änderung Date Klasse mit as.Date mit korrekten format ist), und die erste Beobachtung erhalten mit head

library(data.table) 
setDT(df1)[order(Date), head(.SD, 1), by = ID] 
+0

Ich bin nicht allzu vertraut mit 'Daten .tisch'. Was macht 'head (.SD, 1)' in diesem Fall? – user122514

+0

@ user122514 '.SD' bedeutet Subset von Data.table,' head' mit 1 erhält die erste Zeile jeder Gruppe nach der Bestellung von Datum – akrun

+0

Dies funktionierte perfekt. Vielen Dank! – user122514

1

Hier ist eine weitere Möglichkeit, grundlegende R mit:

earliestDates = aggregate(list(date = df$date), list(ID = df$ID), min) 
result = merge(earliestDates,df) 

earliestDates ist eine zweispaltige Datenrahmen, der die minimale Datum von ID hat. Die Zusammenführung wird den Werten in den anderen Spalten hinzugefügt.

Beispiel:

set.seed(1) 
ID = floor(runif(20,1,5)) 
day = as.Date(floor(runif(20,1,25)),origin = "2017-1-1") 
weight = floor(runif(20,80,95)) 
df = data.frame(ID = ID, date = day, weight = weight) 

> df 
    ID  date weight 
1 2 2017-01-24  92 
2 2 2017-01-07  89 
3 3 2017-01-17  91 
4 4 2017-01-05  88 
5 1 2017-01-08  87 
6 4 2017-01-11  91 
7 4 2017-01-02  80 
8 3 2017-01-11  87 
9 3 2017-01-22  90 
10 1 2017-01-10  90 
11 1 2017-01-13  87 
12 1 2017-01-16  92 
13 3 2017-01-13  86 
14 2 2017-01-06  83 
15 4 2017-01-21  81 
16 2 2017-01-18  81 
17 3 2017-01-21  84 
18 4 2017-01-04  87 
19 2 2017-01-19  89 
20 4 2017-01-11  86 

Nach dem aggregate und merge, das Ergebnis ist:

> result 
    ID  date weight 
1 1 2017-01-08  87 
2 2 2017-01-06  83 
3 3 2017-01-11  87 
4 4 2017-01-02  80 
1

Versuchen Sie, die folgenden dplyr Code:

library(dplyr) 

set.seed(12345) 

###Create test dataset 
tb <- tibble(id = rep(1:10, each = 3), 
      date = rep(seq(as.Date("2017-07-01"), by=10, len=10), 3), 
      obs = rnorm(30)) 

# # A tibble: 30 × 3 
# id  date  obs 
# <int>  <date>  <dbl> 
#  1 2017-07-01 0.5855288 
#  1 2017-07-11 0.7094660 
#  1 2017-07-21 -0.1093033 
#  2 2017-07-31 -0.4534972 
#  2 2017-08-10 0.6058875 
#  2 2017-08-20 -1.8179560 
#  3 2017-08-30 0.6300986 
#  3 2017-09-09 -0.2761841 
#  3 2017-09-19 -0.2841597 
#  4 2017-09-29 -0.9193220 
# # ... with 20 more rows 

###Pipe the dataset through dplyr's 'group_by' and 'filter' commands 
tb %>% group_by(id) %>% 
    filter(date == min(date)) %>% 
    ungroup() %>% 
    distinct() 

# # A tibble: 10 × 3 
# id  date  obs 
# <int>  <date>  <dbl> 
# 1  2017-07-01 0.5855288 
# 2  2017-07-31 -0.4534972 
# 3  2017-08-30 0.6300986 
# 4  2017-07-01 -0.1162478 
# 5  2017-07-21 0.3706279 
# 6  2017-08-20 0.8168998 
# 7  2017-07-01 0.7796219 
# 8  2017-07-11 1.4557851 
# 9  2017-08-10 -1.5977095 
# 10  2017-09-09 0.6203798 
+0

Wirklich mochte diese Idee, da dplyr macht meinen Code viel sauberer. Es funktioniert jedoch nicht für meinen Datenrahmen. Nicht sicher warum. – user122514

+0

Herausgefunden, was falsch ist ... doppelte IDs sind immer noch vorhanden, aus irgendeinem Grund. – user122514

+0

Hmmm, versuchen Sie am Ende mit einem Aufruf von 'distinct()' auf ein anderes Rohr zu heften. Habe die Antwort aktualisiert, um dies zu berücksichtigen. –