r相当于sql update?

时间:2014-03-18 18:15:57

标签: sql r

我环顾四周,但我无法找到一个简单的答案。 如何在SQL中执行更新表? 例如:

> df1 = data.frame(id=seq(1:3), v1=c("a", "b", NA))
> df1
  id   v1
1  1    a
2  2    b
3  3 <NA>
> df2 = data.frame(id=seq(1:3), v2=c("z", "y", "c"))
> df2
  id v2
1  1  z
2  2  y
3  3  c

如何在v1中使用v2中的值更新df1,但仅在id匹配且id为&gt;时更新df1。 2? 我已经查看了data.table,但是无法弄清楚:=语法,并希望基础R中有一些简单的东西?期望的输出将是:

> df1
  id   v1
1  1    a
2  2    b
3  3    c

2 个答案:

答案 0 :(得分:1)

如果df1中的ID不在df2中,并且订单不同,则会更新。只要只有一个id列,就可以使用此功能:

df1 <- data.frame(id=seq(1:5), v1=c("a", "b", NA, NA, NA), stringsAsFactors=F)
df2 <- data.frame(id=seq(1:3), v2=c("z", "y", "c"), stringsAsFactors=F)

df1[df1$id > 2, -1] <- df2[df1$id[df1$id > 2], -1]
df1

产地:

  id   v1
1  1    a
2  2    b
3  3    c
4  4 <NA>
5  5 <NA>

这是一个简单的解决方案,只要两个数据帧都具有相同的ID集,就可以正常工作:

df1[df1$id > 2, ] <- df2[df1$id > 2, ]

产地:

  id v1
1  1  a
2  2  b
3  3  c

但请注意,v1v2必须是字符,因此默认情况下运行此为factor

df1$v1 <- as.character(df1$v1)    
df2$v2 <- as.character(df2$v2)

如果您需要加入多个列,或者如果一个表中的ID不存在于另一个表中,则可以使用mergedata.table将两个变量放在一个表上,然后通过将列与ifelse组合来构造新列。

答案 1 :(得分:1)

SQLite 可以通过sqldf在sqlite中使用更新:

library(sqldf)

sqldf(c("update df1 
         set v1 = (select v2 from df2 where df2.id = df1.id) 
         where id > 2", 
        "select * from df1"))

给出:

  id v1
1  1  a
2  2  b
3  3  c

MySQL 这适用于MySQL:

library(RMySQL)
library(sqldf)

sqldf(c("update df1 
  left join df2 on (df1.id = df2.id and df1.id > 2)
  set df1.v1 = coalesce(df2.v2, df1.v1)",
  "select * from df1")
)

,并提供:

  id v1
1  1  a
2  2  b
3  3  c

基础R 这也有效。前两行只是将v1和v2转换为字符,如果v1和v2已经是字符,则可以避免它们:

df1c <- transform(df1, v1 = as.character(v1))
df2c <- transform(df2, v2 = as.character(v2))
transform(df1c, v1 = ifelse(id > 2, df2c[match(id, df2c$id), "v2"], v1))

更新已合并评论并添加了基本R解决方案。