質問

An example of my data is as follows:

site<-c("A","B","C","D")
year1<-c(1990,1990,1990,1990)
year2<-c("",1991,1991,1991)
year3<-c(1992,1992,1992,1992)
year4<-c(1993,"",1993,"")
year5<-c(1994,1994,1994,1994)
dat<-data.frame(site,year1,year2,year3,year4,year5)

I would like to calculate the range of data for each row (or site in this example) but I would like to include breaks where missing values exist.

So creating a column that resembles something like this.

dat$year_range<-c("1990, 1992-1994","1990-1992, 1994","1990-1994","1990-1992, 1994")

Thanks.

役に立ちましたか?

解決

Here's a proposal, I suppose it could be done in a simpler way:

dat$year_range <- apply(dat[-1], 1, function(x) {
  x <- as.integer(x)
  paste(tapply(x[!is.na(x)], cumsum(is.na(x))[!is.na(x)], function(y) 
    paste(unique(range(y)), collapse = "-")), collapse = ", ")
})

#   site year1 year2 year3 year4 year5      year_range
# 1    A  1990        1992  1993  1994 1990, 1992-1994
# 2    B  1990  1991  1992        1994 1990-1992, 1994
# 3    C  1990  1991  1992  1993  1994       1990-1994
# 4    D  1990  1991  1992        1994 1990-1992, 1994

他のヒント

Here's some regex-fu for you (read/try from inside out):

gsub(',+', ',', # final cleanup of multiple commas
  gsub('(^,+|,+$)', '',  # cleanup of commas at end of start
    # the meat - take out adjacent years and replace them with a '-'
    gsub('((?<=,,)|^)([0-9]+),([0-9]+,)+([0-9]+)((?=,,)|$)',
        ',\\2-\\4,',
        apply(dat[, -1], 1, paste, collapse = ","), perl = TRUE)))
#[1] "1990,1992-1994" "1990-1992,1994" "1990-1994"      "1990-1992,1994"
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top