r-使用数据帧列中的下一个非na值计算

r-使用数据帧列中的下一个非na值计算,r,lag,lead,R,Lag,Lead,我在数据框中有一些数据,我想计算月份值之间的百分比变化。问题是,我在一些条目中有NA,它会抛出计算结果 irm code price pct.change 1 201807 511130F075A04 4.6600 2.192982 2 201806 511130F075A04 4.5600 1.333333 3 201805 511130F075A04 4.5000 -13.461538 4 201804

我在数据框中有一些数据,我想计算
月份
值之间的百分比变化。问题是,我在一些条目中有
NA
,它会抛出计算结果

       irm     code        price    pct.change
1  201807 511130F075A04      4.6600   2.192982
2  201806 511130F075A04      4.5600   1.333333
3  201805 511130F075A04      4.5000 -13.461538
4  201804 511130F075A04      5.2000         NA
5  201803 511130F075A04          NA         NA
6  201802 511130F075A04      4.9100   1.867220
7  201801 511130F075A04      4.8200  -5.304519
8  201712 511130F075A04      5.0900   2.414487
9  201711 511130F075A04      4.9700  -3.307393
10 201710 511130F075A04      5.1400         NA
11 201709 511130F075A04          NA         NA
12 201708 511130F075A04      5.2900   2.918288
13 201707 511130F075A04      5.1400  66.553255
14 201706 511130F075A04      3.0861 -10.664351
15 201705 511130F075A04      3.4545  -7.241824
问题出现在
pct.change
列的第4行和第10行。它们是
NA
,但我希望使用
price
的最新值计算它们,该值不是
NA
。所需的输出为(见第4行和第10行):


我已经尝试了标准的
(x/lead(x)-1)*100
,以及使用
(x/lag)的几个变体(它是.na(lead(x))
但我似乎遗漏了一些东西。在
base
或甚至
dplyr
中有没有一种简单的方法可以做到这一点?我不想替换NAs,我想保留它们。

@LAP的评论可能是最好的方法。数据的语法稍微好一点。table

library(data.table)
setDT(df)

df[!is.na(price), pct.change := 100*(price/shift(price, type = 'lead') - 1)]

#        irm          code  price pct.change
#  1: 201807 511130F075A04 4.6600   2.192982
#  2: 201806 511130F075A04 4.5600   1.333333
#  3: 201805 511130F075A04 4.5000 -13.461538
#  4: 201804 511130F075A04 5.2000   5.906314
#  5: 201803 511130F075A04     NA         NA
#  6: 201802 511130F075A04 4.9100   1.867220
#  7: 201801 511130F075A04 4.8200  -5.304519
#  8: 201712 511130F075A04 5.0900   2.414487
#  9: 201711 511130F075A04 4.9700  -3.307393
# 10: 201710 511130F075A04 5.1400  -2.835539
# 11: 201709 511130F075A04     NA         NA
# 12: 201708 511130F075A04 5.2900   2.918288
# 13: 201707 511130F075A04 5.1400  66.553255
# 14: 201706 511130F075A04 3.0861 -10.664351
# 15: 201705 511130F075A04 3.4545         NA

@LAP的评论可能是最好的方法。使用
data.table时语法稍微好一点

library(data.table)
setDT(df)

df[!is.na(price), pct.change := 100*(price/shift(price, type = 'lead') - 1)]

#        irm          code  price pct.change
#  1: 201807 511130F075A04 4.6600   2.192982
#  2: 201806 511130F075A04 4.5600   1.333333
#  3: 201805 511130F075A04 4.5000 -13.461538
#  4: 201804 511130F075A04 5.2000   5.906314
#  5: 201803 511130F075A04     NA         NA
#  6: 201802 511130F075A04 4.9100   1.867220
#  7: 201801 511130F075A04 4.8200  -5.304519
#  8: 201712 511130F075A04 5.0900   2.414487
#  9: 201711 511130F075A04 4.9700  -3.307393
# 10: 201710 511130F075A04 5.1400  -2.835539
# 11: 201709 511130F075A04     NA         NA
# 12: 201708 511130F075A04 5.2900   2.918288
# 13: 201707 511130F075A04 5.1400  66.553255
# 14: 201706 511130F075A04 3.0861 -10.664351
# 15: 201705 511130F075A04 3.4545         NA

在Base R中,您可以决定替换:

 a = which(is.na(df$price))-1
 transform(df,pct.change=replace(pct.change,a,100*(price[a]/price[a+2]-1)))
      irm          code  price pct.change
1  201807 511130F075A04 4.6600   2.192982
2  201806 511130F075A04 4.5600   1.333333
3  201805 511130F075A04 4.5000 -13.461538
4  201804 511130F075A04 5.2000   5.906314
5  201803 511130F075A04     NA         NA
6  201802 511130F075A04 4.9100   1.867220
7  201801 511130F075A04 4.8200  -5.304519
8  201712 511130F075A04 5.0900   2.414487
9  201711 511130F075A04 4.9700  -3.307393
10 201710 511130F075A04 5.1400  -2.835539
11 201709 511130F075A04     NA         NA
12 201708 511130F075A04 5.2900   2.918288
13 201707 511130F075A04 5.1400  66.553255
14 201706 511130F075A04 3.0861 -10.664351
15 201705 511130F075A04 3.4545  -7.241824

在Base R中,您可以决定替换:

 a = which(is.na(df$price))-1
 transform(df,pct.change=replace(pct.change,a,100*(price[a]/price[a+2]-1)))
      irm          code  price pct.change
1  201807 511130F075A04 4.6600   2.192982
2  201806 511130F075A04 4.5600   1.333333
3  201805 511130F075A04 4.5000 -13.461538
4  201804 511130F075A04 5.2000   5.906314
5  201803 511130F075A04     NA         NA
6  201802 511130F075A04 4.9100   1.867220
7  201801 511130F075A04 4.8200  -5.304519
8  201712 511130F075A04 5.0900   2.414487
9  201711 511130F075A04 4.9700  -3.307393
10 201710 511130F075A04 5.1400  -2.835539
11 201709 511130F075A04     NA         NA
12 201708 511130F075A04 5.2900   2.918288
13 201707 511130F075A04 5.1400  66.553255
14 201706 511130F075A04 3.0861 -10.664351
15 201705 511130F075A04 3.4545  -7.241824

df$pct.change[!is.na(df$price)]我喜欢这样,但是当我在完整的
data.frame上使用它时,我得到了以下警告:
要替换的项目数不是替换长度的倍数
。不过在本例中它确实很有效。
df$pct.change[!is.na(df$price)]我喜欢这样,但当我在完整的
数据中使用它时。frame
我得到以下警告:
要替换的项目数不是替换长度的倍数。尽管如此,它在示例中确实工作得很好。这非常聪明。但如果连续行中有2个
NA
,该怎么办?@jvalenti即使答案也会被接受面对同样的问题。您必须确定解决方法否,
数据中的row参数。表中使用的
语法指定计算集中在
price!=NA
的行上,因此它只会转移到满足该条件的列中的下一个值。这非常聪明。但是如果c中有2个
NA
,该怎么办关于连续行?@jvalenti即使是接受的答案也会面临同样的问题。您必须确定解决方法否,
数据中的row参数。表中使用的
语法指定计算集中在
price!=NA
的行上,因此它只会转移到满足该条件的列中的下一个值。