【发布时间】:2019-08-07 11:21:15
【问题描述】:
我有一个数据框,我想用另一个数据框(查找数据框)中的信息进行更新。
特别是,我想根据 id 和 id2 列将 df1$value 的单元格更新为 df2$value 的单元格。
- 如果
df1$value的单元格是NA,我知道如何使用包data.table
但是
- 如果
df1$value的单元格不为空,data.table 无论如何都会用df2$value的单元格更新它。
我不想那样。我想要那个:
如果df1$value 的单元格不为空(在这种情况下,df1$id 所在的行是c),请不要更新该单元格,而是创建一个重复的 df1 行,其中 df1$value 的单元格从df2$value的单元格中获取值
我已经在网上寻找解决方案,但我找不到任何解决方案。有没有办法使用 tidyverse 或 data.table 或 sql-like 包轻松完成?
感谢您的帮助!
编辑:我刚刚意识到我忘了把两个数据帧中的行都是 NA 的极端情况放在其中。根据我到目前为止的回复 (07/08/19 14:42),行 e 已从最后一个数据帧中删除。但我真的需要保留它!
大纲:
> df1
id id2 value
1 a 1 100
2 b 2 101
3 c 3 50
4 d 4 NA
5 e 5 NA
> df2
id id2 value
1 c 3 200
2 d 4 201
3 e 5 NA
# I'd like:
> df5
id id2 value
1 a 1 100
2 b 2 101
3 c 3 50
4 c 3 200
5 d 4 201
6 e 5 NA
这就是我设法解决我的问题的方法,但它很麻烦。
# I create the dataframes
df1 <- data.frame(id=c('a', 'b', 'c', 'd'), id2=c(1,2,3,4),value=c(100, 101, 50, NA))
df2 <- data.frame(id=c('c', 'd', 'e'),id2=c(3,4, 5), value=c(200, 201, 300))
# I first do a left_join so I'll have two value columnes: value.x and value.y
df3 <- dplyr::left_join(df1, df2, by = c("id","id2"))
# > df3
# id id2 value.x value.y
# 1 a 1 100 NA
# 2 b 2 101 NA
# 3 c 3 50 200
# 4 d 4 NA 201
# I keep only the rows in which value.x is NA, so the 4th row
df4 <- df3 %>%
filter(is.na(value.x)) %>%
dplyr::select(id, id2, value.y)
# > df4
# id id2 value.y
# 1 d 4 201
# I rename the column "value.y" to "value". (I don't do it with dplyr because the function dplyr::replace doesn't work in my R version)
colnames(df4)[colnames(df4) == "value.y"] <- "value"
# > df4
# id id2 value
# 1 d 4 201
# I update the df1 with the df4$value. This step is necessary to update only the rows of df1 in which df1$value is NA
setDT(df1)[setDT(df4), on = c("id","id2"), `:=`(value = i.value)]
# > df1
# id id2 value
# 1: a 1 100
# 2: b 2 101
# 3: c 3 50
# 4: d 4 201
# I filter only the rows in which both value.x and value.y are NAs
df3 <- as_tibble(df3) %>%
filter(!is.na(value.x), !is.na(value.y)) %>%
dplyr::select(id, id2, value.y)
# > df3
# # A tibble: 1 x 3
# id id2 value.y
# <chr> <dbl> <dbl>
# 1 c 3 200
# I rename column df3$value.y to value
colnames(df3)[colnames(df3) == "value.y"] <- "value"
# I bind by rows df1 and df3 and I order by the column id
df5 <- rbind(df1, df3) %>%
arrange(id)
# > df5
# id id2 value
# 1 a 1 100
# 2 b 2 101
# 3 c 3 50
# 4 c 3 200
# 5 d 4 201
【问题讨论】:
标签: r dataframe dplyr data.table