为什么NA​​s出现在数据帧的某些子集中的某些有效(不缺失)变量中

时间:2015-01-21 20:11:31

标签: r dataframe unique subset na

这个问题令我感到困惑;我不是一个体验R用户,所以我所做的可能并不优雅,但并不复杂,我也不了解这个问题。

我从一个有6列和几百行的简单数据框开始。数据列为年,月,日和三个数字变量。可能有多个行具有相同的Year,Month和Day值。这是一个例子:

> thisFrame
    Year Month Day trans_fac   dist     var
1   2003     3  23   42.3475  1.858 1.48190
2   2003     3  23   42.3475  2.779 1.42260
3   2003     3  23   42.3475  4.145 1.39150
4   2003     3  23   42.3475  5.069 1.37860
5   2003     3  23   42.3475  6.439 1.42050
6   2003     3  23   42.3475  8.736 2.54290
7   2003     3  23   42.3475  9.661 1.29120
8   2003     3  23   42.3475 11.040 1.24360
9   2003     3  23   42.3475 11.960 1.32190
10  2003     3  23   42.3475 13.340 1.34820
11  2003     3  23   42.3475 14.270 1.34630
12  2003     3  23   42.3475 15.640 1.37820
13  2003     3  23   42.3475 16.570 1.39550
[some rows snipped]
24  2003     3  23   42.3475 29.840 1.09530
25  2003     4  11   42.3475  2.091 2.62980
26  2003     4  11   42.3475  3.557 1.61910
27  2003     4  11   42.3475  5.446 1.03760
28  2003     4  11   42.3475  7.099 0.93600
29  2003     4  11   42.3475  8.798 1.02190
30  2003     4  11   42.3475 10.630 1.03940
31  2003     4  11   42.3475 12.240 0.96743
32  2003     4  11   42.3475 14.110 0.95497

因为我想独立操作每一天的数据,我计算每一行的Julian(unix)日,并将变量jdays添加到数据框中,然后找到唯一的日期。

days <- as.Date(ISOdate(thisFrame$Year,thisFrame$Month,thisFrame$Day))
thisFrame$jdays  <- as.integer(days)
uniq_days <- unique(thisFrame$jdays)           
nudays    <- length(uniq_days)          # number of unique days

然后我循环查看唯一天数并通过基于唯一日子化原始帧来创建新数据框。然后我想打印操作的结果以及输入集的日,月和年。应该简单吧?好吧,结果正是我有时想要的,有时,即使它们存在于子集中,我也得到日,月和年的NA值。我已经尝试了几个不同的输入数据框架,并且没有找到任何可以帮助我理解为什么会发生这种情况的模式。

for (i in 1:nudays) {
 thisSet <- thisFrame[thisFrame$jdays == uniq_days[i],]
 print(thisSet)
 print(c(i, thisSet$Day[i], thisSet$Month[i], thisSet$Year[i])
}

预期结果:

[1] "This is subset  1"
   Year Month Day trans_fac   dist     var jdays
1  2003     3  23   44.4335  2.011 1.12240 12134
2  2003     3  23   44.4335  3.180 0.92435 12134
3  2003     3  23   44.4335  4.147 0.95406 12134
[lines snipped]
28 2003     3  23   44.4335 29.870 0.75302 12134
[1]    1    3   23 2003
[1] "This is subset  2"
   Year Month Day trans_fac   dist     var jdays
29 2003     3  26   44.4335  3.514 1.01300 12137
30 2003     3  26   44.4335  5.275 0.74062 12137
31 2003     3  26   44.4335  7.031 0.67548 12137
[lines snipped]
45 2003     3  26   44.4335 31.220 0.58399 12137
[1]    2    3   26 2003

等。直到我们到达

[1] "This is subset  18"
    Year Month Day trans_fac   dist     var jdays
358 2003     8  18   44.4335  2.075 0.85803 12282
359 2003     8  18   44.4335  3.524 0.71728 12282
[lines snipped]
374 2003     8  18   44.4335 30.320 0.76502 12282
[1] 18 NA NA NA

but then, we back to expected behavior

[1] "This is subset  19"
    Year Month Day trans_fac   dist     var jdays
375 2003     8  19   44.4335  2.475 1.17220 12283
376 2003     8  19   44.4335  3.875 0.87088 12283
[lines snipped]
397 2003     8  19   44.4335 30.070 0.76463 12283
[1]   19    8   19 2003

直到我们到达

[1] "This is subset  21"
    Year Month Day trans_fac   dist     var jdays
418 2003     9   2   44.4335  1.781 2.00410 12297
419 2003     9   2   44.4335  3.783 0.96007 12297
420 2003     9   2   44.4335  5.479 0.85195 12297
[lines snipped]
433 2003     9   2   44.4335 28.530 0.89522 12297
[1] 21 NA NA NA

回到预期的结果

[1] "This is subset  24"
    Year Month Day trans_fac   dist     var jdays
464 2003     9  17   44.4335  1.173 1.80490 12312
465 2003     9  17   44.4335  2.587 1.04510 12312
[lines snipped]
487 2003     9  17   44.4335 29.770 0.82791 12312
[1]   24    9   17 2003

等等。

我没有看到这个问题,并希望得到任何建议。感谢。

1 个答案:

答案 0 :(得分:3)

问题是

print(c(i, thisSet$Day[i], thisSet$Month[i], thisSet$Year[i])

每个julian日期的i值都会增加,但thisSet只包含特定日期的值。因此,如果第10天(i==10)只有三行(nrows(thisSet)==3),那么您将尝试索引不存在的thisSet的第10个元素。我不确定您要在那里打印什么,但将i替换为1可以通过始终选择第一行来阻止NA值。

print(c(i, thisSet$Day[1], thisSet$Month[1], thisSet$Year[1])

但这真的不是拆分data.frame的好方法。如何使用split()命令

split(thisFrame, thisFrame[,c("Year","Month","Day")], drop=TRUE)

或者,如果要将函数应用于每个子集,可以使用by()命令。