r

Wyodrębnij wiersze pierwszego wystąpienia zmiennej w ramce danych


Mam ramkę danych z dwiema zmiennymi, datą i taksonami, i chcę uzyskać datę pierwszego wystąpienia każdego taksonu. Istnieje 9 różnych dat i 40 różnych taksonów w ramce danych zawierającej 172 wiersze, ale moja odpowiedź powinna obejmować tylko 40 wierszy.
Taksony to czynnik, a data to data.
Na przykład moja ramka danych (nazywana „gatunkiem”) jest skonfigurowana w następujący sposób:
Date Taxa
2013-07-12 A
2011-08-31 B
2012-09-06 C
2012-05-17 A
2013-07-12 C
2012-09-07 B

i szukałbym odpowiedzi takiej:
Date Taxa
2012-05-17 A
2011-08-31 B
2012-09-06 C

Próbowałem użyć:
t.first <- species[unique(species$Taxa),]

co dało mi prawidłową liczbę linii, ale były zduplikowane taksony. Jeśli użyję tylko unikalnego (gatunek $ Taxa), wydaje mi się, że daje mi poprawną odpowiedź, ale wtedy nie wiem, kiedy to się po raz pierwszy wydarzyło.
Dzięki za wszelką pomoc.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

t.first <- species[match(unique(species$Taxa), species$Taxa),]

match
zwraca indeksy pierwszego dopasowania w porównywanych wektorach, co daje żądane ciągi.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Poniższe polecenie
duplicated
tworzy indeks logiczny dla zduplikowanych wartości
data $ Taxa
. Tworzony jest podzbiór ramki danych bez pasujących wierszy za pomocą:
data[!duplicated(data$Taxa), ]

Wynik:
Date Taxa
1 2012-05-17 A
2 2011-08-31 B
3 2012-09-06 C
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto parametr
dplyr
, który jest niezależny od sortowania danych w kolejności dat i bierze pod uwagę relacje:
library(dplyr)
df %>%
mutate(Date = as.Date(Date)) %>%
group_by(Taxa) %>%
filter(Date == min(Date)) %>%
slice(1) %>% # takes the first occurrence if there is a tie
ungroup()# A tibble: 3 x 2
Date Taxa
<date> <chr>
1 2012-05-17 A
2 2011-08-31 B
3 2012-09-06 C # sample data:
df <- read.table(text = 'Date Taxa
2013-07-12 A
2011-08-31 B
2012-09-06 C
2012-05-17 A
2013-07-12 C
2012-09-07 B', header = TRUE, stringsAsFactors = FALSE)

Możesz uzyskać to samo, sortując według daty:
df %>% 
mutate(Date = as.Date(Date)) %>%
group_by(Taxa) %>%
arrange(Date) %>%
slice(1) %>%
ungroup()
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To powinno załatwić sprawę:
# Create some dummy data:# Create some dates 
Date=as.POSIXct(c("2013-07-12","2011-08-31","2012-09-06","2009-01-01",
"2012-05-17","2013-07-12","2012-09-07","2013-02-02"))# Create unique taxa
Taxa=rep(c("A","B","C","D"),2)# Combine the two into a dataframe
data=as.data.frame(list(Date=Date,Taxa=Taxa))# this returns a numeric vector of the minimum dates
xx=tapply(data$Date,list(data$Taxa),min)# And this will return a dataframe with the first occurence
# of your taxa (or variables)
as.data.frame(list(Date=as.POSIXct(xx,origin="1970-01-01"),
Taxa=names(xx)))

Uwaga: Możesz dodać simplify = T, aby dotknąć, aby powrócić
obiekt POSIXt, ale zwraca listę. Więcej szczegółów można znaleźć tutaj:

Nieoczekiwane zachowanie Min, Taply i Posixct/Posixlt Classes?
http://r.789695.n4.nabble.com/ ... .html
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto rozwiązanie wykorzystujące
data.table
:
library(data.table)
setDT(species)
species[, .SD[which.min(Date)], by = Taxa]
# Taxa Date
# 1: A 2012-05-17
# 2: B 2011-08-31
# 3: C 2012-09-06
Dane

:
species <- data.frame( Date = as.Date(c("2013-07-12", "2011-08-31", "2012-09-06", 
"2012-05-17", "2013-07-12", "2012-09-07")),
Taxa = c("A", "B", "C", "A", "C", "B"))

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się