【发布时间】:2019-04-29 21:16:24
【问题描述】:
我正在尝试合并两个相对较大的数据集。我正在通过 SiteID 进行合并 - 这是位置和日期/时间的唯一指标,由年、月 = 月、日和小时 = 小时组成。
问题是merge 在某处丢弃数据。最小值、最大值、平均值和中值都发生了变化,当它们应该是相同的数据时,只需合并即可。我已将数据转换为字符并检查字符串是否匹配,但仍然丢失数据。我也试过left_join,但这似乎没有帮助。详情见下文。
编辑:合并正在删除数据,因为并非每个 ("SiteID", "Year","Mo","Day", "Hr") 都存在数据。因此,我需要在合并之前从dB 中插入缺失值(请参阅下面的答案)。
结束编辑
查看页面底部的链接以重现此示例。
PC17$Mo<-as.character(PC17$Mo)
PC17$Year<-as.character(PC17$Year)
PC17$Day<-as.character(PC17$Day)
PC17$Hr<-as.character(PC17$Hr)
PC17$SiteID<-as.character(PC17$SiteID)
dB$Mo<-as.character(dB$Mo)
dB$Year<-as.character(dB$Year)
dB$Day<-as.character(dB$Day)
dB$Hr<-as.character(dB$Hr)
dB$SiteID<-as.character(dB$SiteID)
# confirm that data are stored as characters
str(PC17)
str(dB)
现在比较我的 SiteID 值,我使用 unique 来查看我有哪些字符串,并使用 setdiff 来查看 R 是否将任何字符串识别为缺失。每个站点都缺少一个站点ID,但这没关系,因为数据中确实缺少它(不是字符串问题)。
sort(unique(PC17$SiteID))
sort(unique(dB$SiteID))
setdiff(PC17$SiteID, dB$SiteID) ## TR2U is the only one missing, this is ok
setdiff(dB$SiteID, PC17$SiteID) ## FI7D is the only one missing, this is ok
现在,当我查看数据(按 SiteID 汇总)时,它看起来像是一个不错的完整数据框 - 这意味着我拥有每个网站的数据,我应该拥有。
library(dplyr)
dB %>%
group_by(SiteID) %>%
summarise(
min_dBL50=min(dbAL050, na.rm=TRUE),
max_dBL50=max(dbAL050, na.rm=TRUE),
mean_dBL50=mean(dbAL050, na.rm=TRUE),
med_dBL50=median(dbAL050, na.rm=TRUE)
)
# A tibble: 59 x 5
SiteID min_dBL50 max_dBL50 mean_dBL50 med_dBL50
<chr> <dbl> <dbl> <dbl> <dbl>
1 CU1D 35.3 57.3 47.0 47.6
2 CU1M 33.7 66.8 58.6 60.8
3 CU1U 31.4 55.9 43.1 43.3
4 CU2D 40 58.3 45.3 45.2
5 CU2M 32.4 55.8 41.6 41.3
6 CU2U 31.4 58.1 43.9 42.6
7 CU3D 40.6 59.5 48.4 48.5
8 CU3M 35.8 75.5 65.9 69.3
9 CU3U 40.9 59.2 46.6 46.2
10 CU4D 36.6 49.1 43.6 43.4
# ... with 49 more rows
在这里,我通过"SiteID", "Year","Mo","Day", "Hr" 合并两个数据集 PC17 和 dB - 保留所有 PC17 值(即使它们没有与之匹配的 dB 值;all.x=TRUE)。
但是,当我查看这些数据的摘要时,现在所有的SiteID 都有不同的值,并且某些站点完全缺失,例如“CU3D”和“CU4D”。
PCdB<-(merge(PC17, dB, by=c("SiteID", "Year","Mo","Day", "Hr"), all.x=TRUE))
PCdB %>%
group_by(SiteID) %>%
summarise(
min_dBL50=min(dbAL050, na.rm=TRUE),
max_dBL50=max(dbAL050, na.rm=TRUE),
mean_dBL50=mean(dbAL050, na.rm=TRUE),
med_dBL50=median(dbAL050, na.rm=TRUE)
)
# A tibble: 59 x 5
SiteID min_dBL50 max_dBL50 mean_dBL50 med_dBL50
<chr> <dbl> <dbl> <dbl> <dbl>
1 CU1D 47.2 54 52.3 54
2 CU1M 35.4 63 49.2 49.2
3 CU1U 35.3 35.3 35.3 35.3
4 CU2D 42.3 42.3 42.3 42.3
5 CU2M 43.1 43.2 43.1 43.1
6 CU2U 43.7 43.7 43.7 43.7
7 CU3D Inf -Inf NaN NA
8 CU3M 44.1 71.2 57.6 57.6
9 CU3U 45 45 45 45
10 CU4D Inf -Inf NaN NA
# ... with 49 more rows
我将所有内容都设置为第一行中带有as.character() 的字符。此外,我检查了Year、Day、Mo 和Hr 与setdiff 和unique,就像我在上面对SiteID 所做的那样,似乎没有任何问题那些不匹配的字符串。
我也尝试过dplyr 函数left_join 来合并数据集,但并没有什么不同。
【问题讨论】:
-
您确定不只是有几个
NA值使您的summarise()计算返回NA?例如,您没有指定min(dbAL050, na.rm=TRUE)。任何涉及NA的计算都会返回NA- 例如:min(c(1,10,NA)) -
你说每个表中都有其他行不匹配。因此 PCdB 具有从外部连接总结为 NA 的 NA。 minimal reproducible example 中的“最小”包括尽可能使用已知的输入、中间和结果数据。调试的绝对基础说:表明你的程序在通过(子)表达式时做了你期望的事情,说明它是什么,并通过增量输出显示它实际上是这样做的。在添加您无法修复的问题代码时,请研究(手册和网络)。重复,尽量减少工作代码和错误代码。然后询问工作示例和非工作示例之间的(小)差异。
-
感谢 cmets。
na.rm=TRUE确实帮助摆脱了很多 NA,但在某处仍然缺少数据。合并后最小值没有那么低,最大值也没有那么高。 @thelatemail - 我在上面的问题中添加了您的建议。
标签: r join merge interpolation imputets