使用dplyr
和函數來確定結果並使代碼更清潔的解決方案。數據:
data <- read.table(text="ID YEAR GIFT
1 2005 $10
1 2006 $5
1 2008 $15
1 2009 $20
1 2010 $20", header=TRUE)
爲了得到你想要的,我們必須比較每個值(this
),以它的前面(prev
)輸出,下一個(follow
),並檢查它的first
或組last
。
getStatus <- function(first, prev, this, follow, last) {
if (first) {
status <- "FIRST" #Easy one
} else if (length(prev) < 1 || is.na(prev)) { #Not the first, but prev missing
status <- "PREVIOUS GIVER"
} else if (this < prev) { #The next 3 are obvious
status <- "LOWER"
} else if (this == prev) {
status <- "SAME"
} else if(this > prev) {
status <- "HIGHER"
}
if ((length(follow) < 1 || is.na(follow)) & !last) { #No next but isn't last
status <- paste(status, "also NO NEXT YEAR")
}
return(status)
}
現在我們有了我們的功能,我們必須處理數據。我們將使用dplyr使事情更具可讀性。
library(dplyr)
result <- data %>% group_by(ID) %>%
arrange(YEAR) %>% #We make sure YEAR is sorted ascending
mutate(gift.num = GIFT %>% gsub("\\$", "", .) %>% as.numeric) %>% #Create a column with the gifts as numbers
mutate(RESULT = sapply(YEAR, function(y) {
#Apply getStatus passing the corresponding arguments to create RESULT
getStatus(.$YEAR %>% first == y, .$gift.num[which(.$YEAR==y-1)],
.$gift.num[which(.$YEAR==y)], .$gift.num[which(.$YEAR==y+1)],
.$YEAR %>% last == y)
})) %>%
select(-gift.num) #Removing the dummy column
這給我們:
ID YEAR GIFT RESULT
1 1 2005 $10 FIRST
2 1 2006 $5 LOWER also NO NEXT YEAR
3 1 2008 $15 PREVIOUS GIVER
4 1 2009 $20 HIGHER
5 1 2010 $20 SAME
更多的數據會更好,以確保所有情況下都包括在內,但即使沒有,與你應該能夠修復任何錯誤。
這將是很好,如果你的例子是可重複的,在這裏描述的意義上:http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example因爲它是,目前還不清楚你的專欄是否是因素或字符/字符串。 – Frank
對不起,我是新來的(第一個問題)。我願意將這些年份的性格,數字或因素作爲最佳工作方式。禮物是數字,ID#是優選的因素/字符,但如果需要可以是數字。 – Dave1956
看看'data.table'開發版本中的'shift'函數(關於SO的一些最近的問題應該給你舉例)。這將回答你的大部分問題。 'dt [,first:=。I == 1,by = id]'會給你第一個禮物的指示器(確保它是按年排序的) – MichaelChirico