如何使用R中的if语句重新整形数据集

时间:2014-07-24 15:21:28

标签: r

我有这种格式的数据集:

ID Sex Age Test1Date  Test1results Test1retakedate Test1retakeresult 

1   F   18  7/25/2000    60         1/1/2001           70              
2   M   19  7/25/2000    61         2/5/2002           90               
3   M   17  2/5/2000     70         5/7/2000           100    

MM / DD / YYYY, 我想要做的是以这种格式:

ID Sex Age TestDates Test1Results  test1retakenresults
1   F  18   7/25/2000     60               NA
1   F  18   1/1/2001      NA               70
2   M  19   7/25/2000     61               NA         
3   M  17   2/5/2000      70               NA
3   M  17   5/7/2000      NA              100

有几个条件:如果重拍的日期是在测试日期的一年内,那么重拍的结果我希望它们出现。如果没有继续下一个。 一。我的问题是我不知道如何将来自许多不同列的值合二为一。正如您所看到的,日期必须在一列中,同样适用于其余列。

2 个答案:

答案 0 :(得分:1)

我建议填充新的数据框,这样您就可以将数据合并到列中并重命名列。

df    <- # Your Current Dataframe
newDF <- data.frame(ID = 0,  Sex = 0, Age = 0, TestDates = 0, test1Results = 0, test1retakenresults = 0)


j <- 1                               # j loops through new dataframe

for (i in 1:nrow(df)) {              # i loops through old dataframe

   newDF[j,] <- c(df[i,][1:5], NA)   # Copy old row

   if (isWithinYear(df$Test1Date[i], df$Test1retakedate[i])) {

      # Add new row if the test dates are within a year
      newDF <- rbind(newDF[1:j,], unlist(c(df[i,][1:3], df$Test1retakedate[i], 
                                     NA, df$Test1retakeresult[i])))
      j <- j + 1
    } 
 j <- j + 1
}

如果您还没有isWithinYear函数我使用日期包创建了一个

isWithinYear <- function(date1, date2) {  

  require(date)

  rawDate <- strptime(date.mmddyyyy(as.date(date1)), "%m/%d/%Y") - 
             strptime(date.mmddyyyy(as.date(date2)), "%m/%d/%Y")

  if (abs(as.integer(rawDate)) < 365) TRUE else FALSE

 }

答案 1 :(得分:0)

您可以使用tidyr将所有测试日期提取到同一列中:

df <- read.table(textConnection("ID Sex Age Test1Date  Test1results Test1retakedate Test1retakeresult 
1   F   18  7/25/2000    60         1/1/2001           70              
2   M   19  7/25/2000    61         2/5/2002           90               
3   M   17  2/5/2000     70         5/7/2000           100    "), header = TRUE)

library(tidyr)

gather(df,vals,TestDates,contains("ate"))

  ID Sex Age Test1results Test1retakeresult            vals TestDates
1  1   F  18           60                70       Test1Date 7/25/2000
2  1   F  18           60                70 Test1retakedate  1/1/2001
3  2   M  19           61                90       Test1Date 7/25/2000
4  2   M  19           61                90 Test1retakedate  2/5/2002
5  3   M  17           70               100       Test1Date  2/5/2000
6  3   M  17           70               100 Test1retakedate  5/7/2000

这样可以更轻松地实现其余步骤。