在R中如何使用ave函数并避免NA值?

8

我有一个庞大的数据框。它看起来像这样:

> b
       fips      vix
1400  08005 18.58862
1401  47155 10.93712
1402  51191 10.93712
1403  47059 10.93712
1404  08005 10.93712
1405  08059 10.93712
1406  47063 10.93712
1407  37021 10.93712
1408  08031 10.93712
1409  45083 10.93712
1410  37089 10.93712
1411  37113 10.93712
1412  13207 10.93712
1413  08041 10.93712
1414  47093 21.50425
1415  08031 21.50425
1416  37009 21.50425
1417  36103 21.50425
1418  08035 21.50425
1419  08031 53.58363
1420  08035 53.58363
1421  08013 53.58363
1422  55105 21.17450
1423  08001 21.17450
1424  08031 21.17450
1425  47179 21.17450
1426  08059 21.17450
1427  37009 17.35675
1428  08041 17.35675
1429  08031 17.35675
1430  08005 17.35675
1431  08001       NA
1432  08031       NA
1433  47059       NA
1434  47145       NA
1435  13207       NA
1436  37021       NA
1437  37113       NA
1438  37089       NA

出于简单起见,我删除了一些列,并且仅展示了一小部分行。 我试图更改Vix列。我的目标是这样做:

b$vix <- b$vix - ave(b$vix,b$fips)

该代码应该执行的操作是从每个Vix值中减去组平均值。例如,对于观察值1400,我想要取所有fips == 08005的观察值的平均值,然后用18.58862减去该平均值。 然而,问题在于存在NA值。我希望平均函数忽略NA值。但实际上,只要一个fips代码组中有一个NA值,整个组都会变成NA:

> b$vix <- b$vix - ave(b$vix,b$fips)
> b
       fips        vix
1400  08005   2.961125
1401  47155   0.000000
1402  51191   0.000000
1403  47059         NA
1404  08005  -4.690375
1405  08059  -5.118688
1406  47063   0.000000
1407  37021         NA
1408  08031         NA
1409  45083   0.000000
1410  37089         NA
1411  37113         NA
1412  13207         NA
1413  08041  -3.209812
1414  47093   0.000000
1415  08031         NA
1416  37009   2.073750
1417  36103   0.000000
1418  08035 -16.039688
1419  08031         NA
1420  08035  16.039688
1421  08013   0.000000
1422  55105   0.000000
1423  08001         NA
1424  08031         NA
1425  47179   0.000000
1426  08059   5.118688
1427  37009  -2.073750
1428  08041   3.209812
1429  08031         NA
1430  08005   1.729250
1431  08001         NA
1432  08031         NA
1433  47059         NA
1434  47145         NA
1435  13207         NA
1436  37021         NA
1437  37113         NA
1438  37089         NA

如您所见,任何具有NA的fips现在将对所有其他具有相同fips的行提供NA。
我尝试添加na.rm=TRUE,但没有效果。我也在考虑添加另一个函数,即ave(b$vix,b$fips,FUN=...),但不知道要添加什么。也许有另一种完全不同的方法来解决这个问题。
希望我能清楚地解释问题。感谢您的所有帮助!
1个回答

13

您可以使用自定义函数将 na.rm=TRUE 标志传递给 mean() 函数。

b$vix <- b$vix - ave(b$vix,b$fips, FUN=function(x) mean(x, na.rm=T))

已测试通过

b<-read.table(text="      fips      vix
08005 18
08005 19
08005 20
47155 10
47155 NA
47155 20", header=T)

b$vix <- b$vix - ave(b$vix,b$fips, FUN=function(x) mean(x, na.rm=T))
b
#    fips vix
# 1  8005  -1
# 2  8005   0
# 3  8005   1
# 4 47155  -5
# 5 47155  NA
# 6 47155   5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接