kmc*_*coy 10 r uniqueidentifier unique-key dataframe data.table
我有数据,其中两个变量("ManufactererId"和"ProductId")的组合构成唯一的键/标识符.数据如下所示:
my.data <- data.frame(ManufactererId = c(1, 1, 2, 2),
ProductId = c(1, 2, 1, 7),
Price = c(12.99, 149.00, 0.99, 3.99))
my.data
# ManufactererId ProductId Price
# 1 1 1 12.99
# 2 1 2 149.00
# 3 2 1 0.99
# 4 2 7 3.99
Run Code Online (Sandbox Code Playgroud)
我想确保我不会意外地添加另一行ManufactererId - ProductId等于表中已存在的行(就像数据库表上的唯一约束一样).
也就是说,如果我尝试向我的数据框添加ManufactererId = 2和ProductId = 7的行:
my.data <- rbind(my.data, data.frame(ManufactererId = 2, ProductId = 7, Price = 120.00))
Run Code Online (Sandbox Code Playgroud)
......它应该失败并出错.怎么能实现这一目标?
或者我应该使用不同的数据类型?
1)zoo是否方便取决于你想要做什么操作,但动物园对象有唯一索引.我们可以通过将两个Id列粘贴在一起来构造文本索引.
library(zoo)
z <- with(my.data, zoo(Price, paste(ManufactererId, ProductId)))
z <- c(z, zoo(90, "1 1")) # Error, not appended
z <- c(z, zoo(90, "1 3")) # OK
Run Code Online (Sandbox Code Playgroud)
请注意,动物园对象的数据部分可以是如上所示的向量,也可以是矩阵,以防您在数据中只有Price.
2)SQLite 这可以使用许多数据库中的任何一个来完成,但我们将在这里使用SQLite.首先,我们在SQLite数据库中创建一个具有唯一索引的表,然后插入行.
library(RSQLite)
con <- dbConnect(SQLite())
dbWriteTable(con, "my", my.data, row.names = FALSE)
dbGetQuery(con, "create unique index ix on my(ManufactererId, ProductId)")
dbGetQuery(con, sprintf("insert into my values(%d, %d, %d)", 1, 1, 99)) # error
dbGetQuery(con, sprintf("insert into my values(%d, %d, %d)", 1, 13, 90)) # OK
Run Code Online (Sandbox Code Playgroud)
你可以这样做:keys你的唯一钥匙在哪里
append_save <- function(DF, to_be_appended, keys=c("ManufactererId", "ProductId")){
if(ncol(DF) != ncol(to_be_appended) || !all(names(DF) %in% names(to_be_appended))){
stop("must have the same columns")
}
if(nrow(merge(DF, to_be_appended, by=keys))==0){
rbind(DF, to_be_appended)
} else {
stop("Trying to append douplicated indices")
}
}
Run Code Online (Sandbox Code Playgroud)
测试一下:
to_be_appended = data.frame(ManufactererId=2,ProductId=17,Price=3.99)
append_save(my.data, to_be_appended) # works
to_be_appended_err = data.frame(ManufactererId=2,ProductId=7,Price=3.99)
append_save(my.data, to_be_appended_err) # error
Run Code Online (Sandbox Code Playgroud)
如果仅根据键列附加数据,则可以data.table按如下方式使用:
append_save <- function(DF, to_be_appended, keys=c("ManufactererId", "ProductId")){
if(!all(keys %in% names(to_be_appended))){
stop("key-columns must be present")
}
if(nrow(data.table::merge(DF, to_be_appended, on=keys))==0){
data.table::setDF(data.table::rbindlist(list(DF, to_be_appended), fill = TRUE))[]
} else {
stop("Trying to append douplicated indices")
}
}
Run Code Online (Sandbox Code Playgroud)