我环顾四周,但我无法找到一个简单的答案。 如何在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
答案 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
但请注意,v1
和v2
必须是字符,因此默认情况下运行此为factor
:
df1$v1 <- as.character(df1$v1)
df2$v2 <- as.character(df2$v2)
如果您需要加入多个列,或者如果一个表中的ID不存在于另一个表中,则可以使用merge
或data.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解决方案。