R:将一个数据框中的行数据按组转换为另一个数据框中的列数据
R: Turning row data from one dataframe into column data by group in another
我有以下格式的数据:
ID
Age
Sex
1
29
M
2
32
F
3
18
F
4
89
M
5
45
M
和;
ID
subID
Type
Status
Year
1
3
Car
Y
1
11
Toyota
NULL
2011
1
23
Kia
NULL
2009
2
5
Car
N
3
2
Car
Y
3
4
Honda
NULL
2019
3
7
Fiat
NULL
2006
3
8
Mitsubishi
NULL
2020
4
1
Car
N
5
7
Car
Y
第二个 table 中的每个 ID 都有一行指定他们是否有车,还有一行说明他们拥有的 car/s 品牌。每个人最多拥有3辆车。我想将这些数据简化为单个 table。
ID
Age
Sex
Car?
Car.1
Car1.year
Car.2
Car2.year
Car.3
Car3.year
1
29
M
Y
Toyota
2011
Kia
2009
NULL
NULL
2
32
F
N
NULL
NULL
NULL
NULL
NULL
NULL
3
18
F
Y
Honda
2019
Fiat
2006
Mitsubishi
2020
4
89
M
N
NULL
NULL
NULL
NULL
NULL
NULL
5
45
M
Y
NULL
NULL
NULL
NULL
NULL
NULL
我已经尝试将 dplyr 中的 mutate 函数与 case_when 函数一起使用,但我无法检查另一个数据帧中的条件。如果我尝试将 table 连接在一起,我会为每个 ID 设置多行,这是我想避免的。第二个 table 的非标准设置使事情变得复杂。我唯一剩下的想法是切换到 Python/Pandas 并创建一个 for 循环,慢慢循环遍历每个 ID,如果此人有汽车和汽车品牌,则搜索第二个数据框,然后改变第一个数据框中的列。但是鉴于我的数据集的大小,这将是低效的并且需要很长时间。
最好的方法是什么?
您可以尝试以下代码:
library(tidyverse)
df1
# A tibble: 5 x 3
ID Age Sex
<dbl> <dbl> <chr>
1 1 29 M
2 2 32 F
3 3 18 F
4 4 89 M
5 5 45 M
df2
# A tibble: 10 x 5
ID subID Type Status Year
<dbl> <dbl> <chr> <chr> <dbl>
1 1 3 Car Y NA
2 1 11 Toyota Y 2011
3 1 23 Kia Y 2009
4 2 5 Car N NA
5 3 2 Car Y NA
6 3 4 Honda Y 2019
7 3 7 Fiat Y 2006
8 3 8 Mitsubishi Y 2020
9 4 1 Clothed N NA
10 5 7 Clothed Y NA
df2 <- df2 %>% mutate(Status = if_else(Status == "NULL", "Y", Status))
df3 <- df2 %>% filter(!is.na(Year)) %>% group_by(ID) %>% mutate(index = row_number())
df4 <- df3 %>% pivot_wider(id_cols = c(ID), values_from = c(Type, Year), names_from = index )
所以你想要的输出将产生:
df1 %>% left_join(df2 %>% select(ID, Status) %>% distinct()) %>% left_join(df4)
# A tibble: 5 x 10
ID Age Sex Status Type_1 Type_2 Type_3 Year_1 Year_2 Year_3
<dbl> <dbl> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 1 29 M Y Toyota Kia NA 2011 2009 NA
2 2 32 F N NA NA NA NA NA NA
3 3 18 F Y Honda Fiat Mitsubishi 2019 2006 2020
4 4 89 M N NA NA NA NA NA NA
5 5 45 M Y NA NA NA NA NA NA
我有以下格式的数据:
ID | Age | Sex |
---|---|---|
1 | 29 | M |
2 | 32 | F |
3 | 18 | F |
4 | 89 | M |
5 | 45 | M |
和;
ID | subID | Type | Status | Year |
---|---|---|---|---|
1 | 3 | Car | Y | |
1 | 11 | Toyota | NULL | 2011 |
1 | 23 | Kia | NULL | 2009 |
2 | 5 | Car | N | |
3 | 2 | Car | Y | |
3 | 4 | Honda | NULL | 2019 |
3 | 7 | Fiat | NULL | 2006 |
3 | 8 | Mitsubishi | NULL | 2020 |
4 | 1 | Car | N | |
5 | 7 | Car | Y |
第二个 table 中的每个 ID 都有一行指定他们是否有车,还有一行说明他们拥有的 car/s 品牌。每个人最多拥有3辆车。我想将这些数据简化为单个 table。
ID | Age | Sex | Car? | Car.1 | Car1.year | Car.2 | Car2.year | Car.3 | Car3.year |
---|---|---|---|---|---|---|---|---|---|
1 | 29 | M | Y | Toyota | 2011 | Kia | 2009 | NULL | NULL |
2 | 32 | F | N | NULL | NULL | NULL | NULL | NULL | NULL |
3 | 18 | F | Y | Honda | 2019 | Fiat | 2006 | Mitsubishi | 2020 |
4 | 89 | M | N | NULL | NULL | NULL | NULL | NULL | NULL |
5 | 45 | M | Y | NULL | NULL | NULL | NULL | NULL | NULL |
我已经尝试将 dplyr 中的 mutate 函数与 case_when 函数一起使用,但我无法检查另一个数据帧中的条件。如果我尝试将 table 连接在一起,我会为每个 ID 设置多行,这是我想避免的。第二个 table 的非标准设置使事情变得复杂。我唯一剩下的想法是切换到 Python/Pandas 并创建一个 for 循环,慢慢循环遍历每个 ID,如果此人有汽车和汽车品牌,则搜索第二个数据框,然后改变第一个数据框中的列。但是鉴于我的数据集的大小,这将是低效的并且需要很长时间。
最好的方法是什么?
您可以尝试以下代码:
library(tidyverse)
df1
# A tibble: 5 x 3
ID Age Sex
<dbl> <dbl> <chr>
1 1 29 M
2 2 32 F
3 3 18 F
4 4 89 M
5 5 45 M
df2
# A tibble: 10 x 5
ID subID Type Status Year
<dbl> <dbl> <chr> <chr> <dbl>
1 1 3 Car Y NA
2 1 11 Toyota Y 2011
3 1 23 Kia Y 2009
4 2 5 Car N NA
5 3 2 Car Y NA
6 3 4 Honda Y 2019
7 3 7 Fiat Y 2006
8 3 8 Mitsubishi Y 2020
9 4 1 Clothed N NA
10 5 7 Clothed Y NA
df2 <- df2 %>% mutate(Status = if_else(Status == "NULL", "Y", Status))
df3 <- df2 %>% filter(!is.na(Year)) %>% group_by(ID) %>% mutate(index = row_number())
df4 <- df3 %>% pivot_wider(id_cols = c(ID), values_from = c(Type, Year), names_from = index )
所以你想要的输出将产生:
df1 %>% left_join(df2 %>% select(ID, Status) %>% distinct()) %>% left_join(df4)
# A tibble: 5 x 10
ID Age Sex Status Type_1 Type_2 Type_3 Year_1 Year_2 Year_3
<dbl> <dbl> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
1 1 29 M Y Toyota Kia NA 2011 2009 NA
2 2 32 F N NA NA NA NA NA NA
3 3 18 F Y Honda Fiat Mitsubishi 2019 2006 2020
4 4 89 M N NA NA NA NA NA NA
5 5 45 M Y NA NA NA NA NA NA