2012-03-19 22 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