我有这种格式的数据集:
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
有几个条件:如果重拍的日期是在测试日期的一年内,那么重拍的结果我希望它们出现。如果没有继续下一个。 一。我的问题是我不知道如何将来自许多不同列的值合二为一。正如您所看到的,日期必须在一列中,同样适用于其余列。
答案 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
这样可以更轻松地实现其余步骤。