У меня есть датафрейм со столбцом значения для нескольких лет. Годы могут не следовать за последовательностью и могут иметь пропущенный 5-й год. Вот пример dataframe

df = data.frame(code = c("AFG", "AGO", "ALB", "AND", "ARB", "ARE", "ARG", "ARM", "ASM", "ATG", "AUS", "AUT", "AUT", "AUT", "AUT", "ABW", "AFG", "AGO", "ALB", "AND", "ARB", "ARE", "ARG", "ARM", "ARM"),
            PPT = c(123, 42, 23, 5, 42, 4, 23, 25, 42, 23, NA, 5563, 56, 54, 645, 6, 4,53, 656, 65, 5563, 646, 6, 66, 54), 
            Year = c(1990, 1991, 1992, 1993, 1991, 1995, 1996, 1997, 1991, 1992, 2000, 2001, 2002, 2014, 2004, 2005, 2006, 2007, 1960, 2009, NA, 2011, 2012, 2013, 2014))

Я хочу добавить дополнительный столбец, который будет основан на разнице между значением для этого года и года + 5. Ex . Если первый год в столбце года - 1960, но данные по PPT за 1965 год отсутствуют, следовательно, значение в new_col будет NA. Аналогичным образом значение для new_col для 1990 года будет 119 (123-4), NA для 2000 года (данные по PPT за 2005 год отсутствуют), 19 для 1991 года и -2 для 1992 года и так далее.

У меня есть очень замысловатый способ сделать это в Excel, однако я ищу более простое решение в R

1
Arihant 2 Май 2019 в 03:41

2 ответа

Решение для data.table, которое будет работать с отсутствующими / пропущенными годами ...

образцы данных

df = data.frame(code = c("AFG", "AGO", "ALB", "AND", "ARB", "ARE", "ARG", "ARM", "ASM", "ATG", "AUS", "AUT", "AUT", "AUT", "AUT", "ABW", "AFG", "AGO", "ALB", "AND", "ARB", "ARE", "ARG", "ARM", "ARM"),
                PPT = c(123, 42, 23, 5, 23, 4, 23, 25, 6, 634, 5, 5563, 56, 56, 645, 6, 4, 656, 645, 65, 5563, 646, 6, 66, 54), 
                Year = c(1990:2014))

код

library(data.table)
#create a data.table with all years from minimum untill maximum + 5
#so missing years will get a NA!
#perform a by-reference join on these years, by Year
result <- data.table( Year = min(df$Year):(max(df$Year) + 5) )[setDT(df), `:=`(code = i.code, PPT = i.PPT), on = .(Year)]
#calculate the desired column, delete unwanted rows
result[, newcol := PPT - shift(PPT, 5, type = "lead" )][!is.na(code),][]

вывод

#     Year code  PPT newcol
#  1: 1990  AFG  123    119
#  2: 1991  AGO   42     19
#  3: 1992  ALB   23     -2
#  4: 1993  AND    5     -1
#  5: 1994  ARB   23   -611
#  6: 1995  ARE    4     -1
#  7: 1996  ARG   23  -5540
#  8: 1997  ARM   25    -31
#  9: 1998  ASM    6    -50
# 10: 1999  ATG  634    -11
# 11: 2000  AUS    5     -1
# 12: 2001  AUT 5563   5559
# 13: 2002  AUT   56   -600
# 14: 2003  AUT   56   -589
# 15: 2004  AUT  645    580
# 16: 2005  ABW    6  -5557
# 17: 2006  AFG    4   -642
# 18: 2007  AGO  656    650
# 19: 2008  ALB  645    579
# 20: 2009  AND   65     11
# 21: 2010  ARB 5563     NA
# 22: 2011  ARE  646     NA
# 23: 2012  ARG    6     NA
# 24: 2013  ARM   66     NA
# 25: 2014  ARM   54     NA
#     Year code  PPT newcol
2
Wimpel 2 Май 2019 в 10:05

Мы также можем использовать mapply

df$new_col <- mapply(function(x, y) {
     inds = df$Year == y + 5
     if (any(inds))   x - df$PPT[inds] else x
},df$PPT, df$Year)

df
#   code  PPT Year new_col
#1   AFG  123 1990     119
#2   AGO   42 1991      19
#3   ALB   23 1992      -2
#4   AND    5 1993      -1
#5   ARB   23 1994    -611
#6   ARE    4 1995      -1
#7   ARG   23 1996   -5540
#8   ARM   25 1997     -31
#9   ASM    6 1998     -50
#10  ATG  634 1999     -11
#.....
1
Ronak Shah 2 Май 2019 в 01:00