在R中操纵数据帧

时间:2014-04-25 11:44:07

标签: r dataframe

我有一个像

这样的数据框
   ID       DATE         TS_EVENT              X   Y  Z
ID0026A  2013-01-03 2013-01-03 8:31:09 PM     25   0  0
ID0026A  2013-01-03 2013-01-03 8:31:09 PM      0   0  0
ID0026A  2013-01-03 2013-01-03 11:22:55 PM     0   0  0
ID0026A  2013-01-03 2013-01-03 11:36:05 PM     0   0  0
ID0026A  2013-01-03 2013-01-03 11:36:05 PM     0   0  0
ID0026A  2013-03-27 2013-01-03 11:36:05 PM   100 354 25

现在我想返回一个数据框,它将包含四列ID,DATE,X,Y和Z.但是col“ID”将包含唯一ID,DATE将包含该ID的最新日期,其余的cols的值将与该特定ID的最新时间戳(TS_EVENT)对应。

,例如,对于ID0026A,数据框应该看起来像

   ID       DATE       X   Y  Z
ID0026A  2013-03-27    0   0  0
ID0026A  2013-01-03  100 354 25

我的数据框包含120万条记录和6000个唯一ID

注意:ID为str的字符,DATE的str为日期,TS_EVENT的str为字符,其余为数字

所以,首先我要将TS_EVENT转换为日期时间对象,然后创建所需的数据帧。

我怎样才能在R?

中这样做

5 个答案:

答案 0 :(得分:3)

关于数据的大小,我会使用data.table解决方案。

如果您的数据已经排序:

library(data.table)
DT <- as.data.table(dat)
DT[,tail(.SD,1),'ID']
# ID       DATE   X   Y  Z
# 1: ID0026A 2013-03-27 100 354 25

否则:

DT[,.SD[which.max(as.Date(DATE)),],'ID']

PS:dat是:

dat <- read.table(text=" ID       DATE       X   Y  Z
ID0026A  2013-01-03    25   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-03-27   100 354 25",header=T)

data.table的开发版本中,为data.table的fromLastduplicated方法实现了参数unique。因此,您可以这样做(假设该列按ID, DATE排序:

require(data.table) ## >= 1.9.3
unique(setDT(dat), by=c("ID"), fromLast=TRUE)

答案 1 :(得分:2)

以下是三种方法:

df <- read.table(header=T, text="ID       DATE       X   Y  Z
ID0026A  2013-01-03    25   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-01-03     0   0  0
ID0026A  2013-03-27   100 354 25
ID0026B  2013-12-03     0   1  1
ID0026B  2013-11-03     0   0  0", colClasses=c("factor", "Date", rep("integer", 3)))

aggregate(df[order(df$DATE), ], list(df$ID), tail, 1)[-1]

library(dplyr)
df %.% 
  arrange(DATE) %.% 
  group_by(ID) %.%  
  filter(DATE == tail(DATE, 1))

library(data.table)
dt <- data.table(df, key=c("DATE"))
dt[, last(.SD), by="ID"]

答案 2 :(得分:1)

您可以使用dplyr软件包轻松完成此操作:

x <- data.frame(ID=c(1,2,2), DATE=c("2012-01-03","2013-03-01","2013-03-02"), X=c(4,5,6))
df <- group_by(x,ID)
summarise(df, date=DATE[which.max(DATE)], X=X[which.max(DATE)])

如果可能有多个最新日期,那么您可以这样做

# df is the name of your dataframe
library(dplyr)
df %.% group_by(ID) %.% filter(DATE==DATE[which.max(DATE)])

编辑: 可以像这样将TS_EVENT转换为日期时间对象:

df$TS_EVENT <- as.POSIXct(df$TS_EVENT, format="%Y-%m-%d %I:%M:%S %p", tz="UTC")

答案 3 :(得分:1)

如果日期按升序排列,您可以使用:

dat[!duplicated(dat$ID, fromLast = TRUE), ]

答案 4 :(得分:0)

我希望这会有所帮助,但是因为你有1.2万行data.table会更好

library(plyr)
ddply(df,~ID,function(x){x[x$DATE==max(x$DATE),]})