使用merge()可使用第二个数据框中的值更新数据框

r7knjye2  于 2023-05-20  发布在  其他
关注(0)|答案(7)|浏览(83)

我正在试图弄清楚如何使用merge()来更新 Dataframe 。
以 Dataframe foo为例

foo <- data.frame(index=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA))

,它具有下列值

index value
1     a   100
2     b   101
3     c    NA
4     d    NA

以及 Dataframe bar

bar <- data.frame(index=c('c', 'd'), value=c(200, 201))

它具有以下值:

index value
1     c   200
2     d   201

运行以下merge()函数来更新cd的值时

merge(foo, bar, by='index', all=T)

其结果如下:

index value.x value.y
1     a     100      NA
2     b     101      NA
3     c      NA     200
4     d      NA     201

我希望merge()的输出避免创建value.xvalue.y,但只保留value的原始列。

pvabu6sv

pvabu6sv1#

使用data.table的最优解

library(data.table)
setDT(foo)
setDT(bar)
foo[bar, on="index", value:=i.value]
foo
#   index value
#1:     a   100
#2:     b   101
#3:     c   200
#4:     d   201

第一个参数在[数据.表方法被命名为i因此我们可以引用列从表在i参数使用i.前缀.

fivyi3re

fivyi3re2#

merge()不总是将列绑定在一起吗?replace()能用吗?

foo$value <- replace(foo$value, foo$index %in% bar$index, bar$value)

match(),因此顺序很重要

foo$value[match(bar$index, foo$index)] <- bar$value
cmssoen2

cmssoen23#

我还想介绍一个使用库sqldf和R集成的sqlite-database的sql解决方案。我喜欢sql的简单、准确和强大。
准确度:因为我可以精确地定义我想要改变的对象=行,而不考虑data.frame(foo.id = bar.id)的顺序。
Power:在SET和WHERE之后的WHERE(第三行)中,我可以定义所有我想考虑更新的条件。
简单:语法比在向量、矩阵或 Dataframe 中使用索引更易读。

library(sqldf)

# I changed index to id since index does not work. 
#   Obviously index is a key word in sqlite.

(foo <- data.frame(id=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA)))
(bar <- data.frame(id=c('c', 'd'), value=c(200, 201)))

sqldf(c(paste("UPDATE foo"
             ," SET value = (SELECT bar.value FROM bar WHERE foo.id = bar.id)"
             ," WHERE value IS NULL"
             )
        , " SELECT * FROM main.foo"
    )
)

这就给了

id value
1  a   100
2  b   101
3  c   200
4  d   201

类似问题:
r equivalent of sql update?
R sqlite: update with two tables

v2g6jxz6

v2g6jxz64#

merge()仅合并新数据。例如,如果您有几个城市的平均收入数据集,以及这些城市人口的单独数据集,则可以使用merge()将一组数据合并到另一组数据中。
就像apeescape说的,replace()可能就是你想要的。

bnl4lu3b

bnl4lu3b5#

另一种方法可以是:
1.从第一个数据弗拉姆中删除NA
1.使用rbind来追加数据,而不是使用merge:
以下是原始的两个 Dataframe :

foo <- data.frame(index=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA))
bar <- data.frame(index=c('c', 'd'), value=c(200, 201))

(1)使用www.example.com的否定is.na来删除NA:

foo_new <- foo[!is.na(foo$value),]

(2)绑定 Dataframe ,你就会得到你一直在寻找的答案

new_df <- rbind(foo_new,bar)

            new_df
            index value
            1     a   100
            2     b   101
            3     c   200
            4     d   201
pvcm50d1

pvcm50d16#

我认为最简单的方法是在合并之前“标记”需要更新的值。

bar$update <- TRUE
foo <- merge(foo, bar, by='index', all=T, suffixes=c("",".update"))
foo[!is.na(foo$update),]$value <- foo[!is.na(foo$update),]$value.update
foo$value.update <- NULL
foo$update <- NULL

使用“data.table”会更快

library(data.table)
foo <- as.data.table(foo)
bar <- as.data.table(bar)
bar[, update:=TRUE]
foo <- merge(foo, bar, by='index', all=T, suffixes=c("",".update"))
foo[!is.na(update),value:=value.update]
foo[, c("value.update","update"):=NULL]
foo

   index value
1:     a   100
2:     b   101
3:     c   200
4:     d   201
8i9zcol2

8i9zcol27#

我也面临着类似的问题,但与我的相比,这仍然是一个具体的案例。我有两个 Dataframe ,其中左一个是主 Dataframe (如您的情况下的foo),右一个是具有更新值的次要 Dataframe (如您的情况下的bar)。现在我必须更新左数据框中的值,而不是右数据框中的值,只有不同的值。这有点类似于你的问题,但人们已经回答了关于NA的问题。
有关适用于具有非NA值的多行和多列的更通用的解决方案,请参见。

foo <- data.frame(index=c('a', 'b', 'c', 'd'), value=c(100, 101, NA, NA))
bar <- data.frame(index=c('c', 'd'), value=c(200, 201))

ModifiedIndexs <-
  foo %>% 
  full_join(bar) %>% 
  group_by(index) %>% 
  summarise(count = n()) %>% 
  filter(count > 1) %>% 
  pull(index)

UpdatedDF <- foo
UpdatedDF[which(UpdatedDF$index %in% ModifiedIndexs),] <- bar

继续编码!

相关问题