2012-03-19 32 views
1

我有一个csv文件,可以导入到R. 这是一个数据帧,在“长格式”中有很多列,即有多个条目为相同的ID。我正在复制数据集的示例,以及我试图获得的结果数据集,仅使用前5列(实际数据中实际上有更多列)。从史蒂夫根据条件从长格式文件中只选择日期和相关行

df <- data.frame(id = c("id1","id1","id2","id2","id2","id2","id3","id3"), date = c("30/10/20010 from Steve.","30/16/2005 from Anna. 09/08/2008 from Steve. 09/10/2009 from Steve.","06/05/2004 from Allen.","08/09/2005 from Anna.","08/05/2008 from Allen. 30/10/2010 from Bobby.","14/03/2002 from Steve. 23/07/2003 from Anna.","08/08/2002 from Steve.", "08/08/2002 from Anna. 08/08/2002 from Steve."), v1 = c(1,NA,1,1,2,NA,1,2), v2 = c(2,NA,2,NA,NA,NA,2,NA), v3 = c(1,NA,NA,2,NA,1,1,NA), v4 = c("Y","N","N","Y","NA","NA","Y","Y"), v5 = c(0,0,NA,0,0,NA,0,NA)) 

标识日期V1 V2 V3 V4 V5

1 ID1 30/10/20010:原始数据集在R中可以进行复制与此有关。 1 2 1 Y 0

2 id1 30/16/2005 from Anna。 09/08/2008来自Steve。 09/10/2009来自Steve。 NA NA NA N 0

3 id2 06/05/2004 from Allen。 1 2不适用不适用

4 id2 08/09/2005来自Anna。 1 NA 2 Y 0

5 id2 08/05/2008 from Allen。 30/10/2010从鲍比。 2 NA NA NA 0

6 id2 14/03/2002 from Steve。 23/03/2003从安娜。 NA NA 1 NA NA

7 id3 08/08/2002 from Steve。 1 2 1 Y 0

8 id3 08/08/2002 from Anna。 08/08/2002来自Steve。 2 NA NAŸNA

我想获得的数据集选择只与每个ID列date最近日期的行,如果这两个日期都一样,选择与行最少数目的NAS(的缺失值):

标识日期V1 V2 V3 V4 V5

1 ID1 30/10/20010 1 2 1 Y 0

5 ID2 30/10/2010 2不适用不适用0

7 ID3 2002年8月8日1 2 1 Y 0

我想用 “从” 作为分隔符中的R拆分列,但是这并没有真正把我的任何地方:

try<- strsplit(df$date, "from", fixed=TRUE) 

后来我想,这可能是更好的选择BASH日期:但这也用不了我到任何地方:

grep "[0-9][0-9]\/[0-9][0-9]\/20[0-9][0-9]" file.csv | less -S 

基本上,我迷失在如何接近这个。 如果有人可以请建议正确的方法,希望只使用BASH或R,我将非常感激。 谢谢!

回答

1

这里是您的示例数据工作

(后修正两个日期:30/10/20010 --> 30/10/201030/16/2005 --> 30/06/2005)的脚本

df <- data.frame(id = c("id1","id1","id2","id2","id2","id2","id3","id3"), date = c("30/10/2010 from Steve.","30/06/2005 from Anna. 09/08/2008 from Steve. 09/10/2009 from Steve.","06/05/2004 from Allen.","08/09/2005 from Anna.","08/05/2008 from Allen. 30/10/2010 from Bobby.","14/03/2002 from Steve. 23/07/2003 from Anna.","08/08/2002 from Steve.", "08/08/2002 from Anna. 08/08/2002 from Steve."), v1 = c(1,NA,1,1,2,NA,1,2), v2 = c(2,NA,2,NA,NA,NA,2,NA), v3 = c(1,NA,NA,2,NA,1,1,NA), v4 = c("Y","N","N","Y","NA","NA","Y","Y"), v5 = c(0,0,NA,0,0,NA,0,NA)) 

# Convert string to list of dates, extract maximum (earliest date) 
df.dates <- sapply(as.character(df$date), function(x) strsplit(x, "\\.")) 
df.dates <- lapply(df.dates, function(x) as.Date(x, format='%d/%m/%Y')) 
df.dates <- lapply(df.dates, max) 

# Add to dataframe 
df$latest <- unlist(df.dates) 

# Count the number of NA values per row 
df$naCount <- apply(df, 1, function(x) sum(is.na(x[3:7]))) 

# Split data and select either maximum (latest) date or minimal NA count 
df.split <- split(df, df$id) 

df.select <- lapply(df.split, function(x){ 

    # Select by given criterion 
    if(length(unique(x$latest)) == 1){ 
     y <- x[which(min(x$naCount) == x$naCount),] 
     } 
    else{ 
     y <- x[which(max(x$latest) == x$latest),] 
    } 

    # Check if selection was successful 
    if(nrow(y) != 1) cat('Warning: non-unique choice, returning more than one line') 

    # Return result 
    y 
}) 

# Combine into output dataframe 
df.select <- do.call(rbind, df.select) 

脚本的结果是这样的:

> df.select 

    id           date v1 v2 v3 v4 v5 latest naCount 
id1 id1      30/10/2010 from Steve. 1 2 1 Y 0 14912  0 
id2 id2 08/05/2008 from Allen. 30/10/2010 from Bobby. 2 NA NA NA 0 14912  2 
id3 id3      08/08/2002 from Steve. 1 2 1 Y 0 11907  0 
+0

亲爱的yellowcap,非常感谢您的帮助,代码正常工作,在这一步之后只有一些警告:“df.dates < - lapply(df.dates,max)”在“max.default(structure(n umeric(0),class =“Date”),...:没有非缺少参数到max;返回-Inf“,但我猜测我的原始数据集中可能存在问题,你所做的非常聪明,我不认为我现在可以自己做,所以我真的必须研究你的代码 – user971102 2012-03-19 14:49:59

+0

嗨,我刚刚重新检查了这个,它给了我许多错误,问题是当我没有独特的日期以及同一个ID内的重复,所以例如如果我添加了第四个id,如下所示: – user971102 2012-04-13 19:29:27

+0

df < - data.frame(id = c(“id4”,“id4”,“id4”),date = c(“06/08/2002 from Julian。”,“08/08/2002 from Kate。“,”08/08/2002 by Carrie。08/08/2002 from Kate。“),v1 = c(NA,3,NA),v2 = c(NA,2,NA) ,v3 = c(NA,1,NA),v4 = c(“N”,“Y”,“N”),v5 = c(0,0,0)) – user971102 2012-04-13 19:35:02