使用na.approx或na.spline替换矩阵数据中的NA值

3

我是一名刚接触R语言的新手,目前遇到了一个问题,数据看起来像这样:

    ID      h1      h2     h3      h4      h5      h6     h7     h8  
    IP6_1  0.1800   NA    -0.8600  NA      0.0400 -0.1400 1.4400 1.4900  
    IP6_2 -0.0250 -0.3050 -1.1050 -1.2150  0.0250  1.2750 1.7950 1.3850  
    IP6_3  0.2125 -0.1875   NA    -1.2225 -0.1425  0.7325 1.6275 1.3975  
    IP6_4  0.0150   NA    -1.0450 -0.3550  0.2950 -0.0150 0.3850 0.3050  
    IP6_5  0.1200 -0.0900 -0.9100 -0.6500  0.0900 -0.2700 0.9100 1.1200  
    IP6_6  0.0200 -0.0200 -0.8400 -0.6600   NA    -0.0900 0.6200 0.0800 

数据中有随机的NA值,我想使用na.approx替换。

我尝试过使用它:

z_data <- zoo(cluster_data_wf[,-1])        
na.approx(z_data)

该方法并不替换任何NA值。

如果可以通过approx或spline进行线性插值或三次样条插值来替换NA值,将不胜感激。

编辑:最终输出仍应包含第一列ID。

2个回答

3
像这样吗?
require(zoo)
cols = colnames(x[, -1])
x = data.frame(ID=x[, 1], t(apply(x[, -1], 1, na.approx)))
colnames(x)[-1] = cols
print(x)

         ID      h1      h2     h3      h4      h5      h6     h7     h8
1 IP6_1  0.1800 -0.3400 -0.860 -0.4100  0.0400 -0.1400 1.4400 1.4900
2 IP6_2 -0.0250 -0.3050 -1.105 -1.2150  0.0250  1.2750 1.7950 1.3850
3 IP6_3  0.2125 -0.1875 -0.705 -1.2225 -0.1425  0.7325 1.6275 1.3975
4 IP6_4  0.0150 -0.5150 -1.045 -0.3550  0.2950 -0.0150 0.3850 0.3050
5 IP6_5  0.1200 -0.0900 -0.910 -0.6500  0.0900 -0.2700 0.9100 1.1200
6 IP6_6  0.0200 -0.0200 -0.840 -0.6600 -0.3750 -0.0900 0.6200 0.0800

你能解释一下为什么需要删除并重新添加第一行吗? - ro ko
我删除了第一列,因为它是一个字符串/因子,然后对每一行应用了na.approx。你需要转置最终结果。 - Fernando

2

这个问题没有提供可重现的输入,所以我们不知道你从哪里开始。但是,如果我们有一个可以在下面给出的方式重现的输入,那么由于 na.approx 是按列操作的,我们将除了第一列之外的部分进行转置,使用 na.approx,再将其转置回来,并填充除第一列之外的所有内容:

replace(DF, -1, t(na.approx(t(DF[, -1]))))

提供:

     ID      h1      h2     h3      h4      h5      h6     h7     h8
1 IP6_1  0.1800 -0.3400 -0.860 -0.4100  0.0400 -0.1400 1.4400 1.4900
2 IP6_2 -0.0250 -0.3050 -1.105 -1.2150  0.0250  1.2750 1.7950 1.3850
3 IP6_3  0.2125 -0.1875 -0.705 -1.2225 -0.1425  0.7325 1.6275 1.3975
4 IP6_4  0.0150 -0.5150 -1.045 -0.3550  0.2950 -0.0150 0.3850 0.3050
5 IP6_5  0.1200 -0.0900 -0.910 -0.6500  0.0900 -0.2700 0.9100 1.1200
6 IP6_6  0.0200 -0.0200 -0.840 -0.6600 -0.3750 -0.0900 0.6200 0.0800

注意:

Lines <- " ID      h1      h2     h3      h4      h5      h6     h7     h8  
    IP6_1  0.1800   NA    -0.8600  NA      0.0400 -0.1400 1.4400 1.4900  
    IP6_2 -0.0250 -0.3050 -1.1050 -1.2150  0.0250  1.2750 1.7950 1.3850  
    IP6_3  0.2125 -0.1875   NA    -1.2225 -0.1425  0.7325 1.6275 1.3975  
    IP6_4  0.0150   NA    -1.0450 -0.3550  0.2950 -0.0150 0.3850 0.3050  
    IP6_5  0.1200 -0.0900 -0.9100 -0.6500  0.0900 -0.2700 0.9100 1.1200  
    IP6_6  0.0200 -0.0200 -0.8400 -0.6600   NA    -0.0900 0.6200 0.0800 "

DF <- read.table(text = Lines, header = TRUE, as.is = TRUE)

输入数据与您在笔记中所述相同。 - ro ko
但问题声称 na.approx(zoo(DF[, -1])) 忽略了 NAs,这并不是事实。实际上,它会用线性插值替换所有的 NAs,除了在开头或结尾处的 NAs,因为你需要每一侧都有一个值来进行插值。 - G. Grothendieck
你说得对,实际上这个数据跟我的数据并不完全一样。如果有NAs在开头或结尾时就不能被替换。当NA在开头或结尾时,该如何使用na.approx呢? - ro ko
1
na.approx 内部使用 approx 并将参数传递给它,因此您可以使用参数 rule = 2 将最外层的值扩展到端点上的 NAs。有关详细信息,请参见 ?approx 中的 rule 参数。 - G. Grothendieck

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