合并具有不同行数的两个 Dataframe 而不重复行

wz8daaqr  于 2024-01-03  发布在  其他
关注(0)|答案(2)|浏览(139)

假设我有两个名为df和df1的 Dataframe :

df<- data.frame("id" = c(1,1,1,2,2,3,3,4,4,5,5,5),"occ"=c(1,1,2,2,2,1,1,2,2,1,2,2))

df1<- data.frame("id" = c(1,1,2,2,3,3,4,4,5,5),"salary"= c(10,11,12,13,14,15,16,17,18,19))

字符串
我想合并两个基于ID的数据,如果在df1中存在但在df中的某行为零,我的预期输出如下:

id occ salary
1   1   1     10
2   1   1     11
3   1   2      0
4   2   2     12
5   2   2     13
6   3   1     14
7   3   1     15
8   4   2     16
9   4   2     17
10  5   1     18
11  5   2     19
12  5   2      0


我尝试了下面的代码,但它重复行:

merged   <- merge(df, df1, by.x="id", by.y="id") or
merged   <- merge(df, df1, by = "id", all = TRUE)

nszi6y05

nszi6y051#

有一个 * 时间 * 变量丢失,尝试在基地R。

> merge(
+   transform(df, time=ave(id, id, FUN=seq_along)),
+   transform(df1, time=ave(id, id, FUN=seq_along)),
+   all=TRUE
+ )
   id time occ salary
1   1    1   1     10
2   1    2   1     11
3   1    3   2     NA
4   2    1   2     12
5   2    2   2     13
6   3    1   1     14
7   3    2   1     15
8   4    1   2     16
9   4    2   2     17
10  5    1   1     18
11  5    2   2     19
12  5    3   2     NA

字符串
如果你真的想用0替换NA,那么把它放到replace中。

> merge(
+   transform(df, time=ave(id, id, FUN=seq_along)),
+   transform(df1, time=ave(id, id, FUN=seq_along)),
+   all=TRUE
+ ) |> transform(salary=replace(salary, is.na(salary), 0))
   id time occ salary
1   1    1   1     10
2   1    2   1     11
3   1    3   2      0
4   2    1   2     12
5   2    2   2     13
6   3    1   1     14
7   3    2   1     15
8   4    1   2     16
9   4    2   2     17
10  5    1   1     18
11  5    2   2     19
12  5    3   2      0

  • 数据类型:*
> dput(df)
structure(list(id = c(1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5), occ = c(1, 
1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 2)), class = "data.frame", row.names = c(NA, 
-12L))
> dput(df1)
structure(list(id = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5), salary = c(10, 
11, 12, 13, 14, 15, 16, 17, 18, 19)), class = "data.frame", row.names = c(NA, 
-10L))

t3irkdon

t3irkdon2#

由于ID序列对于合并很重要,因此需要添加一个额外的列。

library(dplyr)
df %>% 
  mutate(seq=row_number(), .by=id) %>% 
  left_join(df1 %>% mutate(seq=row_number(), .by=id), by = join_by(id, seq)) %>% 
  select(-seq) %>% 
  mutate(across(-id, ~coalesce(.x, 0)))

字符串
这将返回

id occ salary
1   1   1     10
2   1   1     11
3   1   2      0
4   2   2     12
5   2   2     13
6   3   1     14
7   3   1     15
8   4   2     16
9   4   2     17
10  5   1     18
11  5   2     19
12  5   2      0

相关问题