假设我有一个像myData这样的数据集:
ZonedDateTime startOfDay = ZonedDateTime.ofInstant( Instant.ofEpochSecond( 1466058808L ) , ZoneId.of( "America/Montreal" ) ).toLocalDate().atStartOfDay( ZoneId.of( "America/Montreal" ) );
注意myData没有Date和Species之间的所有可能组合。缺少10行。我想创建一个新的数据框(比如myData2),其中我有Date和Species之间的所有可能组合,即myData 2将有60行。如果myData中存在Date和Species的特定组合,则myData2中的Measurement值应为其原始值,如果缺少此组合,则为NA。
我正在尝试使用两个嵌套的for循环完成此操作,但它无法正常工作。我知道我犯了错误,但我无法弄清楚它们是什么。
答案 0 :(得分:4)
您正在寻找complete
套餐中的tidyr
功能,该功能完全是出于您的目的而设计:
tidyr::complete(myData, Date, Species)
# Source: local data frame [60 x 3]
#
# Date Species Measurement
# (date) (fctr) (dbl)
# 1 1990-01-01 cat -1.2070657
# 2 1990-01-01 cheetah -0.5238281
# 3 1990-01-01 leopard -2.1800396
# 4 1990-01-01 lion -0.7762539
# 5 1990-01-01 tiger -0.6937202
# 6 1990-02-01 cat 0.2774292
# 7 1990-02-01 cheetah -0.4968500
# 8 1990-02-01 leopard -1.3409932
# 9 1990-02-01 lion NA
# 10 1990-02-01 tiger NA
# .. ... ... ...
答案 1 :(得分:2)
我们不需要包裹。可以使用expand.grid
base R
轻松完成
merge(expand.grid(Date=unique(myData$Date),
Species=as.character(unique(myData$Species))), myData, all.x=TRUE)
myData <- data.frame(Date= Date[-index], Species = Species[-index],
Measurement = Measurement[-index])
答案 2 :(得分:1)
为了完整起见,这里还有一个library(data.table)
setDT(myData)[CJ(Date = Date, Species = Species, unique = TRUE), on = .(Date, Species)]
解决方案:
Date Species Measurement
1: 1990-01-01 cat -1.2070657
2: 1990-01-01 cheetah -0.5238281
3: 1990-01-01 leopard -2.1800396
4: 1990-01-01 lion -0.7762539
5: 1990-01-01 tiger -0.6937202
6: 1990-02-01 cat 0.2774292
7: 1990-02-01 cheetah -0.4968500
8: 1990-02-01 leopard -1.3409932
9: 1990-02-01 lion NA
10: 1990-02-01 tiger NA
11: 1990-03-01 cat 1.0844412
12: 1990-03-01 cheetah -1.8060313
13: ...
CJ()
它使用Date
(交叉联接)来创建Species
和myData
的所有唯一组合,并将其与=CONCATENATE(B1;" - Le ";TEXT(C1;"dd/mm/yyyy"))
结合使用。这类似于Akrun's base R approach。