通过 R 中行的均等分布合并 2 Data.frame
Merging 2 Data.frame by equal distribution of Rows in R
我有两个数据框 df_1
和 df_2
超过 5000 个观察值(行)。我想基于 Date
和 Mcode
两个相似的列合并它们,这样行在两个数据框中均匀分布。详情见下文。
>df_1
Date Mcode TNo. BSize
1 1/8/2014 3R72B7K8ZN 1426576 7.2
2 1/8/2014 3R72B7K8ZN 1426578 7.5
3 1/8/2014 3R72B7K8ZN 1426579 7.5
4 1/8/2014 8R55BNW9H5 1426581 7.2
5 1/8/2014 8R55BNW9H5 1426582 7.5
6 1/8/2014 8R55BNW9H5 1426584 7.5
7 1/8/2014 3R72B7K8ZN 1426606 7.5
8 1/8/2014 3R72B7K8ZN 1426610 7.2
9 1/8/2014 8R55BNW9H5 1426621 7.5
10 1/8/2014 8R55BNW9H5 1426624 7.5
11 2/8/2014 4R72B7K9ZN 1426626 7.5
12 2/8/2014 4R72B7K9ZN 1426627 7.5
13 2/8/2014 8R55BNW9H5 1426638 7.2
14 2/8/2014 8R55BNW9H5 1426639 7.2
15 2/8/2014 4R60B6K6ZN 1426699 7.5
16 3/8/2014 4R60B6K6ZN 1426701 1.5
17 3/8/2014 4R72B7K9ZN 1426703 7.5
18 3/8/2014 4R60B6K6ZN 1426704 7.5
19 3/8/2014 4R72B7K9ZN 1426705 7.5
20 3/8/2014 4R72B7K9ZN 1426706 7.2
和类似的第二个数据帧如下。
>df_2
Date Mcode X28days X7days
1 1/8/2014 3R72B7K8ZN 64.0 51.1
2 1/8/2014 3R72B7K8ZN 65.0 51.6
3 1/8/2014 8R55BNW9H5 75.4 58.4
4 1/8/2014 8R55BNW9H5 78.7 57.1
5 2/8/2014 4R72B7K9ZN 75.7 58.8
6 2/8/2014 4R72B7K9ZN 73.9 56.9
7 2/8/2014 8R55BNW9H5 77.3 60.8
8 2/8/2014 4R60B6K6ZN 62.6 48.5
9 3/8/2014 4R72B7K9ZN 71.2 56.1
10 4/8/2014 4R60B6K6ZN 59.3 46.8
11 4/8/2014 4R60B6K7ZN 68.5 51.2
我想合并 df_1
和 df_2
,这样得到的 df_3
(行数与 df_1
的行数相同)应该如下所示
>df_3
Date Mcode TNo. BSize X28days X7days
1 1/8/2014 3R72B7K8ZN 1426576 7.2 64.0 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 64.0 51.1
3 1/8/2014 3R72B7K8ZN 1426579 7.5 64.0 51.1
4 1/8/2014 8R55BNW9H5 1426581 7.2 75.4 58.4
5 1/8/2014 8R55BNW9H5 1426582 7.5 75.4 58.4
6 1/8/2014 8R55BNW9H5 1426584 7.5 75.4 58.4
7 1/8/2014 3R72B7K8ZN 1426606 7.5 65.0 51.6
8 1/8/2014 3R72B7K8ZN 1426610 7.2 65.0 51.6
9 1/8/2014 8R55BNW9H5 1426621 7.5 78.7 57.1
10 1/8/2014 8R55BNW9H5 1426624 7.5 78.7 57.1
11 2/8/2014 4R72B7K9ZN 1426626 7.5 75.7 58.8
12 2/8/2014 4R72B7K9ZN 1426627 7.5 75.7 58.8
13 2/8/2014 8R55BNW9H5 1426638 7.2 77.3 60.8
14 2/8/2014 8R55BNW9H5 1426639 7.2 77.3 60.8
15 2/8/2014 4R60B6K6ZN 1426699 7.5 62.6 48.5
16 3/8/2014 4R60B6K6ZN 1426701 1.5 NA NA
17 3/8/2014 4R72B7K9ZN 1426703 7.5 71.2 56.1
18 3/8/2014 4R60B6K6ZN 1426704 7.5 NA NA
19 3/8/2014 4R72B7K9ZN 1426705 7.5 71.2 56.1
20 3/8/2014 4R72B7K9ZN 1426706 7.2 71.2 56.1
如果我们运行df_3%>%filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
,它给出
Date Mcode TNo. BSize X28days X7days
1 1/8/2014 3R72B7K8ZN 1426576 7.2 64 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 64 51.1
3 1/8/2014 3R72B7K8ZN 1426579 7.5 64 51.1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 65 51.6
5 1/8/2014 3R72B7K8ZN 1426610 7.2 65 51.6
见
df_2
的前两行在 df_3
的最终或合并数据集中平均分布。所有行都可以看到类似的合并模式。
笔记:
我希望对大小大于 30x5000(列 x 行)的完整数据集进行这种类型的合并。
在完整的数据
日期是2014年和2015年(700多个日期),Mcode有30多种不同的类型。
谁能帮我解决一下,感激不尽
解决此问题的一种方法是向您的两个数据帧添加一个额外的 id 列。
我在这里称它为 obs_id
。此 id 在 Date
和 Mcode
的每组中设置,以计算各自其他数据框中的最大观察数,然后从 1“重置”。
这看起来如下:
library(dplyr)
df_1a <- df_1 %>%
left_join(
df_2 %>% count(Date, Mcode, name = "df_2_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
obs_id = first(df_2_obs_n) %>%
coalesce(0) %>%
seq() %>%
rep(length.out = n())
) %>%
ungroup() %>%
select(-df_2_obs_n)
df_2a <- df_2 %>%
left_join(
df_1a %>% count(Date, Mcode, name = "df_1_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
obs_id = first(df_1_obs_n) %>%
coalesce(0) %>%
seq() %>%
rep(length.out = n())
) %>%
ungroup() %>%
select(-df_1_obs_n)
对于您的 Date=="1/8/2014", Mcode=="3R72B7K8ZN"
示例组,这会生成如下列:
> df_1a %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 5 x 5
Date Mcode TNo. BSize obs_id
<chr> <chr> <int> <dbl> <int>
1 1/8/2014 3R72B7K8ZN 1426576 7.2 1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 2
3 1/8/2014 3R72B7K8ZN 1426579 7.5 1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 2
5 1/8/2014 3R72B7K8ZN 1426610 7.2 1
> df_2a %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 2 x 5
Date Mcode X28days X7days obs_id
<chr> <chr> <dbl> <dbl> <int>
1 1/8/2014 3R72B7K8ZN 64 51.1 1
2 1/8/2014 3R72B7K8ZN 65 51.6 2
现在,您可以基于该列进行左连接,您将看到 df_2a
中的列“均匀分布”,至少与您预期的一样多。
df_3a <- df_1a %>%
left_join(df_2a, by = c("Date", "Mcode", "obs_id"))
> df_3a %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 5 x 7
Date Mcode TNo. BSize obs_id X28days X7days
<chr> <chr> <int> <dbl> <int> <dbl> <dbl>
1 1/8/2014 3R72B7K8ZN 1426576 7.2 1 64 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 2 65 51.6
3 1/8/2014 3R72B7K8ZN 1426579 7.5 1 64 51.1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 2 65 51.6
5 1/8/2014 3R72B7K8ZN 1426610 7.2 1 64 51.1
由于 obs_id
在 df_1a
中的模式 1,2,1,2,1
中重复,df_2a
中的 table 行的连接顺序是与您上面描述的 df_3
不同。如果这是一个问题,您可以像这样调整 rep(...)
调用:
df_1b <- df_1 %>%
left_join(
df_2 %>%
count(Date, Mcode, name = "df_2_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
df_2_obs_n = coalesce(df_2_obs_n, 1),
obs_id = first(df_2_obs_n) %>%
seq() %>%
rep(length.out = n(), each = ceiling(n()/first(df_2_obs_n)))
) %>%
ungroup() %>%
select(-df_2_obs_n)
df_2b <- df_2 %>%
left_join(
df_1a %>%
count(Date, Mcode, name = "df_1_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
df_1_obs_n = coalesce(df_1_obs_n, 1),
obs_id = first(df_1_obs_n) %>%
seq() %>%
rep(length.out = n(), each = ceiling(n()/first(df_1_obs_n)))
) %>%
ungroup() %>%
select(-df_1_obs_n)
现在,obs_id
重复模式是 1,1,1,2,2
,您将得到您描述的结果。
df_3b <- df_1b %>%
left_join(df_2b, by = c("Date", "Mcode", "obs_id"))
> df_3b %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 5 x 7
Date Mcode TNo. BSize obs_id X28days X7days
<chr> <chr> <int> <dbl> <int> <dbl> <dbl>
1 1/8/2014 3R72B7K8ZN 1426576 7.2 1 64 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 1 64 51.1
3 1/8/2014 3R72B7K8ZN 1426579 7.5 1 64 51.1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 2 65 51.6
5 1/8/2014 3R72B7K8ZN 1426610 7.2 2 65 51.6
我有两个数据框 df_1
和 df_2
超过 5000 个观察值(行)。我想基于 Date
和 Mcode
两个相似的列合并它们,这样行在两个数据框中均匀分布。详情见下文。
>df_1
Date Mcode TNo. BSize
1 1/8/2014 3R72B7K8ZN 1426576 7.2
2 1/8/2014 3R72B7K8ZN 1426578 7.5
3 1/8/2014 3R72B7K8ZN 1426579 7.5
4 1/8/2014 8R55BNW9H5 1426581 7.2
5 1/8/2014 8R55BNW9H5 1426582 7.5
6 1/8/2014 8R55BNW9H5 1426584 7.5
7 1/8/2014 3R72B7K8ZN 1426606 7.5
8 1/8/2014 3R72B7K8ZN 1426610 7.2
9 1/8/2014 8R55BNW9H5 1426621 7.5
10 1/8/2014 8R55BNW9H5 1426624 7.5
11 2/8/2014 4R72B7K9ZN 1426626 7.5
12 2/8/2014 4R72B7K9ZN 1426627 7.5
13 2/8/2014 8R55BNW9H5 1426638 7.2
14 2/8/2014 8R55BNW9H5 1426639 7.2
15 2/8/2014 4R60B6K6ZN 1426699 7.5
16 3/8/2014 4R60B6K6ZN 1426701 1.5
17 3/8/2014 4R72B7K9ZN 1426703 7.5
18 3/8/2014 4R60B6K6ZN 1426704 7.5
19 3/8/2014 4R72B7K9ZN 1426705 7.5
20 3/8/2014 4R72B7K9ZN 1426706 7.2
和类似的第二个数据帧如下。
>df_2
Date Mcode X28days X7days
1 1/8/2014 3R72B7K8ZN 64.0 51.1
2 1/8/2014 3R72B7K8ZN 65.0 51.6
3 1/8/2014 8R55BNW9H5 75.4 58.4
4 1/8/2014 8R55BNW9H5 78.7 57.1
5 2/8/2014 4R72B7K9ZN 75.7 58.8
6 2/8/2014 4R72B7K9ZN 73.9 56.9
7 2/8/2014 8R55BNW9H5 77.3 60.8
8 2/8/2014 4R60B6K6ZN 62.6 48.5
9 3/8/2014 4R72B7K9ZN 71.2 56.1
10 4/8/2014 4R60B6K6ZN 59.3 46.8
11 4/8/2014 4R60B6K7ZN 68.5 51.2
我想合并 df_1
和 df_2
,这样得到的 df_3
(行数与 df_1
的行数相同)应该如下所示
>df_3
Date Mcode TNo. BSize X28days X7days
1 1/8/2014 3R72B7K8ZN 1426576 7.2 64.0 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 64.0 51.1
3 1/8/2014 3R72B7K8ZN 1426579 7.5 64.0 51.1
4 1/8/2014 8R55BNW9H5 1426581 7.2 75.4 58.4
5 1/8/2014 8R55BNW9H5 1426582 7.5 75.4 58.4
6 1/8/2014 8R55BNW9H5 1426584 7.5 75.4 58.4
7 1/8/2014 3R72B7K8ZN 1426606 7.5 65.0 51.6
8 1/8/2014 3R72B7K8ZN 1426610 7.2 65.0 51.6
9 1/8/2014 8R55BNW9H5 1426621 7.5 78.7 57.1
10 1/8/2014 8R55BNW9H5 1426624 7.5 78.7 57.1
11 2/8/2014 4R72B7K9ZN 1426626 7.5 75.7 58.8
12 2/8/2014 4R72B7K9ZN 1426627 7.5 75.7 58.8
13 2/8/2014 8R55BNW9H5 1426638 7.2 77.3 60.8
14 2/8/2014 8R55BNW9H5 1426639 7.2 77.3 60.8
15 2/8/2014 4R60B6K6ZN 1426699 7.5 62.6 48.5
16 3/8/2014 4R60B6K6ZN 1426701 1.5 NA NA
17 3/8/2014 4R72B7K9ZN 1426703 7.5 71.2 56.1
18 3/8/2014 4R60B6K6ZN 1426704 7.5 NA NA
19 3/8/2014 4R72B7K9ZN 1426705 7.5 71.2 56.1
20 3/8/2014 4R72B7K9ZN 1426706 7.2 71.2 56.1
如果我们运行df_3%>%filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
,它给出
Date Mcode TNo. BSize X28days X7days
1 1/8/2014 3R72B7K8ZN 1426576 7.2 64 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 64 51.1
3 1/8/2014 3R72B7K8ZN 1426579 7.5 64 51.1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 65 51.6
5 1/8/2014 3R72B7K8ZN 1426610 7.2 65 51.6
见
df_2
的前两行在 df_3
的最终或合并数据集中平均分布。所有行都可以看到类似的合并模式。
笔记:
我希望对大小大于 30x5000(列 x 行)的完整数据集进行这种类型的合并。
在完整的数据
日期是2014年和2015年(700多个日期),Mcode有30多种不同的类型。
谁能帮我解决一下,感激不尽
解决此问题的一种方法是向您的两个数据帧添加一个额外的 id 列。
我在这里称它为 obs_id
。此 id 在 Date
和 Mcode
的每组中设置,以计算各自其他数据框中的最大观察数,然后从 1“重置”。
这看起来如下:
library(dplyr)
df_1a <- df_1 %>%
left_join(
df_2 %>% count(Date, Mcode, name = "df_2_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
obs_id = first(df_2_obs_n) %>%
coalesce(0) %>%
seq() %>%
rep(length.out = n())
) %>%
ungroup() %>%
select(-df_2_obs_n)
df_2a <- df_2 %>%
left_join(
df_1a %>% count(Date, Mcode, name = "df_1_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
obs_id = first(df_1_obs_n) %>%
coalesce(0) %>%
seq() %>%
rep(length.out = n())
) %>%
ungroup() %>%
select(-df_1_obs_n)
对于您的 Date=="1/8/2014", Mcode=="3R72B7K8ZN"
示例组,这会生成如下列:
> df_1a %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 5 x 5
Date Mcode TNo. BSize obs_id
<chr> <chr> <int> <dbl> <int>
1 1/8/2014 3R72B7K8ZN 1426576 7.2 1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 2
3 1/8/2014 3R72B7K8ZN 1426579 7.5 1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 2
5 1/8/2014 3R72B7K8ZN 1426610 7.2 1
> df_2a %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 2 x 5
Date Mcode X28days X7days obs_id
<chr> <chr> <dbl> <dbl> <int>
1 1/8/2014 3R72B7K8ZN 64 51.1 1
2 1/8/2014 3R72B7K8ZN 65 51.6 2
现在,您可以基于该列进行左连接,您将看到 df_2a
中的列“均匀分布”,至少与您预期的一样多。
df_3a <- df_1a %>%
left_join(df_2a, by = c("Date", "Mcode", "obs_id"))
> df_3a %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 5 x 7
Date Mcode TNo. BSize obs_id X28days X7days
<chr> <chr> <int> <dbl> <int> <dbl> <dbl>
1 1/8/2014 3R72B7K8ZN 1426576 7.2 1 64 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 2 65 51.6
3 1/8/2014 3R72B7K8ZN 1426579 7.5 1 64 51.1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 2 65 51.6
5 1/8/2014 3R72B7K8ZN 1426610 7.2 1 64 51.1
由于 obs_id
在 df_1a
中的模式 1,2,1,2,1
中重复,df_2a
中的 table 行的连接顺序是与您上面描述的 df_3
不同。如果这是一个问题,您可以像这样调整 rep(...)
调用:
df_1b <- df_1 %>%
left_join(
df_2 %>%
count(Date, Mcode, name = "df_2_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
df_2_obs_n = coalesce(df_2_obs_n, 1),
obs_id = first(df_2_obs_n) %>%
seq() %>%
rep(length.out = n(), each = ceiling(n()/first(df_2_obs_n)))
) %>%
ungroup() %>%
select(-df_2_obs_n)
df_2b <- df_2 %>%
left_join(
df_1a %>%
count(Date, Mcode, name = "df_1_obs_n"),
by = c("Date", "Mcode")
) %>%
group_by(Date, Mcode) %>%
mutate(
df_1_obs_n = coalesce(df_1_obs_n, 1),
obs_id = first(df_1_obs_n) %>%
seq() %>%
rep(length.out = n(), each = ceiling(n()/first(df_1_obs_n)))
) %>%
ungroup() %>%
select(-df_1_obs_n)
现在,obs_id
重复模式是 1,1,1,2,2
,您将得到您描述的结果。
df_3b <- df_1b %>%
left_join(df_2b, by = c("Date", "Mcode", "obs_id"))
> df_3b %>% filter(Date=="1/8/2014", Mcode=="3R72B7K8ZN")
# A tibble: 5 x 7
Date Mcode TNo. BSize obs_id X28days X7days
<chr> <chr> <int> <dbl> <int> <dbl> <dbl>
1 1/8/2014 3R72B7K8ZN 1426576 7.2 1 64 51.1
2 1/8/2014 3R72B7K8ZN 1426578 7.5 1 64 51.1
3 1/8/2014 3R72B7K8ZN 1426579 7.5 1 64 51.1
4 1/8/2014 3R72B7K8ZN 1426606 7.5 2 65 51.6
5 1/8/2014 3R72B7K8ZN 1426610 7.2 2 65 51.6