53

我有一个包含两个变量 Date 和 Taxa 的数据框,并且想要获取每个分类单元第一次出现的日期。由 172 行组成的数据框中有 9 个不同的日期和 40 个不同的分类群,但我的答案应该只有 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),]

它给了我正确的行数,但有重复分类。如果我只使用 unique(species$Taxa) 它似乎给了我正确的答案,但是我不知道它第一次发生的日期。

谢谢你的帮助。

4

5 回答 5

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

应该给你你正在寻找的东西。match返回比较向量中第一个匹配项的索引,从而为您提供所需的行。

于 2013-11-13T03:04:31.773 回答
16

在以下命令中,为重复值duplicated创建逻辑索引。data$Taxa没有相应行的数据框的子集是通过以下方式创建的:

data[!duplicated(data$Taxa), ]

结果:

        Date Taxa
1 2012-05-17    A
2 2011-08-31    B
3 2012-09-06    C
于 2013-11-13T04:44:22.900 回答
11

这是一个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()
于 2018-08-11T15:15:35.560 回答
2

这应该可以解决问题:

# 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)))

注意:您可以在 tapply 中添加 simple=T 以返回一个 POSIXt 对象,但它会返回一个列表。可以在此处找到更多信息: min、tapply 和 POSIXct/POSIXlt 类的意外行为?

于 2013-11-13T03:50:50.050 回答
2

这是使用的解决方案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")
)
于 2019-04-09T08:32:45.317 回答