我有两个data.frame时间序列。第一个是完成的,第二个只包含其中一个变量的正确值的时间步长。我需要保留所有其他变量但是想要NA出现在第二个df中的所有变量。这里的例子是:
library(dplyr)
library(tidyverse)
library(lubridate)
#test data:
TDF <- tibble(DATE = seq( make_datetime(2007,09,23,06,00), make_datetime(2008,07,05,23,00), by = 600),
V1 = round(runif(length(DATE)),2),
V2 = round(runif(length(DATE)),2),
V3 = round(runif(length(DATE)),2))
TDF2 <- TDF
TDF2 <- TDF2[TDF2$V1>0.7,]
输出:
> TDF
# A tibble: 41,287 × 4
DATE V1 V2 V3
<dttm> <dbl> <dbl> <dbl>
1 2007-09-23 06:00:00 0.89 0.21 0.03
2 2007-09-23 06:10:00 0.26 0.54 0.70
3 2007-09-23 06:20:00 0.74 0.22 0.80
4 2007-09-23 06:30:00 0.31 0.48 0.38
5 2007-09-23 06:40:00 0.93 0.26 0.21
> TDF2
# A tibble: 11,972 × 4
DATE V1 V2 V3
<dttm> <dbl> <dbl> <dbl>
1 2007-09-23 06:00:00 0.89 0.21 0.03
2 2007-09-23 06:20:00 0.74 0.22 0.80
3 2007-09-23 06:40:00 0.93 0.26 0.21
4 2007-09-23 07:20:00 0.91 0.36 0.83
5 2007-09-23 07:40:00 0.95 0.87 0.91
这就是我需要的:
> TDF_modified
# A tibble: 41,287 × 4
DATE V1 V2 V3
<dttm> <dbl> <dbl> <dbl>
1 2007-09-23 06:00:00 0.89 0.21 0.03
2 2007-09-23 06:10:00 NA 0.54 0.70
3 2007-09-23 06:20:00 0.74 0.22 0.80
4 2007-09-23 06:30:00 NA 0.48 0.38
5 2007-09-23 06:40:00 0.93 0.26 0.21
我只需使用两个data.frames就需要一个通用的解决方案。我可以通过循环来做,但我打赌有一种更优雅的方式。非常感谢先进!
答案 0 :(得分:1)
我并不完全清楚您要查找的内容,但根据您的示例输出,您似乎希望保留来自TDF的V2
和V3
的结果,并且仅删除V1
阅读。
一种方法是使用left_join
而不使用V1
的{{1}}列,而只使用TDF
中的V1
列:
TDF2
给出:
left_join(
select(TDF, -V1)
, select(TDF2, DATE, V1) )
来自我的随机数据。
如果您正在寻找更完整的解决方案,可以执行 DATE V2 V3 V1
<dttm> <dbl> <dbl> <dbl>
1 2007-09-23 06:00:00 0.14 0.62 NA
2 2007-09-23 06:10:00 0.87 0.05 0.87
3 2007-09-23 06:20:00 0.20 0.52 NA
4 2007-09-23 06:30:00 0.34 0.01 NA
5 2007-09-23 06:40:00 0.92 0.37 0.83
6 2007-09-23 06:50:00 0.94 0.27 NA
7 2007-09-23 07:00:00 0.98 0.49 NA
8 2007-09-23 07:10:00 0.70 0.98 NA
9 2007-09-23 07:20:00 0.05 0.55 0.72
10 2007-09-23 07:30:00 0.16 0.12 0.99
,这将产生重复的列,然后根据需要处理它们。例如,如果full_join
丢失,则返回NA
V1
,但对于TDF2$V1
和V2
,如果缺少则会V3
值,并且如果两个值存在且不同,则仅给出TDF
。由于我不确定您要使用什么,因此您可能需要在此处添加更复杂的检查。
NA
返回:
full_join(TDF, TDF2, "DATE") %>%
mutate(V1 = ifelse(is.na(V1.y), NA, V1.x)
, V2 = ifelse(is.na(V2.y), V2.x
, ifelse(V2.x == V2.y, V2.x, NA))
, V3 = ifelse(is.na(V3.y), V3.x
, ifelse(V3.x == V3.y, V3.x, NA))
)
(并且,为了清理重复的列,只需在完成后使用# A tibble: 41,287 × 10
DATE V1.x V2.x V3.x V1.y V2.y V3.y V1 V2 V3
<dttm> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2007-09-23 06:00:00 0.62 0.14 0.62 NA NA NA NA 0.14 0.62
2 2007-09-23 06:10:00 0.87 0.87 0.05 0.87 0.87 0.05 0.87 0.87 0.05
3 2007-09-23 06:20:00 0.53 0.20 0.52 NA NA NA NA 0.20 0.52
4 2007-09-23 06:30:00 0.03 0.34 0.01 NA NA NA NA 0.34 0.01
5 2007-09-23 06:40:00 0.83 0.92 0.37 0.83 0.92 0.37 0.83 0.92 0.37
6 2007-09-23 06:50:00 0.70 0.94 0.27 NA NA NA NA 0.94 0.27
7 2007-09-23 07:00:00 0.51 0.98 0.49 NA NA NA NA 0.98 0.49
8 2007-09-23 07:10:00 0.65 0.70 0.98 NA NA NA NA 0.70 0.98
9 2007-09-23 07:20:00 0.72 0.05 0.55 0.72 0.05 0.55 0.72 0.05 0.55
10 2007-09-23 07:30:00 0.99 0.16 0.12 0.99 0.16 0.12 0.99 0.16 0.12
# ... with 41,277 more rows
。)
答案 1 :(得分:0)
这是一个应该有效的基础R解决方案:
is.na(TDF$V1[setdiff(seq_len(nrow(TDF)), match(TDF$Date, TDF2$Date))]) <- TRUE
match
函数返回TDF中的观察位置,其中TDF2中存在相同的日期。 setdiff
将此输出转换为此集合的补码,即TDF中日期不匹配的观察集合。使用is.na<-
方法将TDF $ V1的值设置为NA以进行观察。