Ответ 1
t.first <- species[match(unique(species$Taxa), species$Taxa),]
должен дать вам то, что вы ищете. match
возвращает индексы первого совпадения в сравниваемых векторах, которые дают вам нужные строки.
У меня есть фрейм данных с двумя переменными: Date и Taxa, и я хочу получить дату в первый раз, когда будут возникать все таксоны. В кадре данных имеется 9 разных дат и 40 различных таксонов, состоящих из 172 строк, но мой ответ должен содержать только 40 строк.
Такси - это фактор, а дата - дата.
Например, мой фрейм данных (называемый "вид" ) создается следующим образом:
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
и я бы хотел найти такой ответ:
Date Taxa
2012-05-17 A
2011-08-31 B
2012-09-06 C
Я попытался использовать:
t.first <- species[unique(species$Taxa),]
и это дало мне правильное количество строк, но повторили Taxa. Если я просто использую уникальный (вид $Taxa), он, как представляется, дает мне правильный ответ, но тогда я не знаю даты его первого появления.
Спасибо за любую помощь.
t.first <- species[match(unique(species$Taxa), species$Taxa),]
должен дать вам то, что вы ищете. match
возвращает индексы первого совпадения в сравниваемых векторах, которые дают вам нужные строки.
В следующей команде duplicated
создается логический индекс для дублированных значений data$Taxa
. Подмножество кадра данных без соответствующих строк создается с помощью:
data[!duplicated(data$Taxa), ]
Результат:
Date Taxa
1 2012-05-17 A
2 2011-08-31 B
3 2012-09-06 C
Это должно сделать трюк:
# 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)))
Примечание. Вы можете добавить simplify = T в ответ, чтобы вернуть POSIXt объект, но возвращает список. Более подробную информацию можно найти здесь: Неожиданное поведение классов min, tapply и POSIXct/POSIXlt?
Вот опция dplyr
которая не зависит от данных, отсортированных в порядке дат и учета связей:
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)
И вы можете получить то же самое, отсортировав по дате:
df %>%
mutate(Date = as.Date(Date)) %>%
group_by(Taxa) %>%
arrange(Date) %>%
slice(1) %>%
ungroup()
Вот решение с использованием 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
Данные:
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")
)