Этот запрос может быть использован в PHP-коде.
У меня есть столбец идентификатора в этой таблице, поэтому мне нужно проверить дублирование для всех столбцов, кроме этого столбца ID:
#need to change values
SET @goodsType = 1, @sybType=5, @deviceId = asdf12345SDFasdf2345;
INSERT INTO `devices` (`goodsTypeId`, `goodsId`, `deviceId`) #need to change tablename and columnsnames
SELECT * FROM (SELECT @goodsType, @sybType, @deviceId) AS tmp
WHERE NOT EXISTS (
SELECT 'goodsTypeId' FROM `devices` #need to change tablename and columns names
WHERE `goodsTypeId` = @goodsType
AND `goodsId` = @sybType
AND `deviceId` = @deviceId
) LIMIT 1;
, и теперь новый элемент будет добавлен только в том случае, если не существует строки со значениями, настроенными в строке SET
Все, что вам нужно сделать, это снова применить factor () к вашей переменной после подмножества:
> subdf$letters
[1] a b c
Levels: a b c d e
subdf$letters <- factor(subdf$letters)
> subdf$letters
[1] a b c
Levels: a b c
EDIT
Из примера страницы факторов:
factor(ff) # drops the levels that do not occur
Для удаления уровней из всех столбцы фактора в кадре данных, вы можете использовать:
subdf <- subset(df, numbers <= 3)
subdf[] <- lapply(subdf, function(x) if(is.factor(x)) factor(x) else x)
Попробовали большинство примеров здесь, если не все ни кроме одного, кажется, работают в моем случае. После борьбы в течение достаточно долгого времени я попытался использовать as.character () на факторном столбце для изменения его на седло со строками, которое кажется тому, чтобы работать просто великолепно.
Не уверенный для проблем производительности.
Это известная проблема, и предлагается одно возможное решение от drop.levels ()
в пакете gdata , где ваш пример становится
> drop.levels(subdf)
letters numbers
1 a 1
2 b 2
3 c 3
> levels(drop.levels(subdf)$letters)
[1] "a" "b" "c"
. Также есть функция dropUnusedLevels
в Hmisc пакет. Однако он работает только путем изменения оператора подмножества [
и здесь не применим.
Как следствие, прямой подход на основе каждого столбца представляет собой простой as.factor (as .character (data))
:
> levels(subdf$letters)
[1] "a" "b" "c" "d" "e"
> subdf$letters <- as.factor(as.character(subdf$letters))
> levels(subdf$letters)
[1] "a" "b" "c"
Это неприятно. Я обычно делаю это так, чтобы не загружать другие пакеты:
levels(subdf$letters)<-c("a","b","c",NA,NA)
, что дает вам:
> subdf$letters
[1] a b c
Levels: a b c
Обратите внимание, что новые уровни заменят все, что занимает их индекс на старых уровнях (subdf $ письма), поэтому что-то вроде:
levels(subdf$letters)<-c(NA,"a","c",NA,"b")
не сработает.
Очевидно, это не идеально, когда у вас много уровней, но для некоторых это быстро и легко.
Если вам не нужно такое поведение, не используйте множители, вместо этого используйте векторы символов. Я думаю, что в этом больше смысла, чем исправлять вещи потом. Попробуйте выполнить следующее перед загрузкой данных с помощью read.table
или read.csv
:
options(stringsAsFactors = FALSE)
Недостатком является то, что вы ограничены алфавитным порядком. (повторный заказ - ваш друг для участков)
Вот еще один способ, который, как мне кажется, эквивалентен подходу с коэффициентом (..)
:
> df <- data.frame(let=letters[1:5], num=1:5)
> subdf <- df[df$num <= 3, ]
> subdf$let <- subdf$let[ , drop=TRUE]
> levels(subdf$let)
[1] "a" "b" "c"
Для этого я написал служебные функции. Теперь, когда я знаю о drop.levels в gdata, он выглядит очень похоже. Вот они (из здесь ):
present_levels <- function(x) intersect(levels(x), x)
trim_levels <- function(...) UseMethod("trim_levels")
trim_levels.factor <- function(x) factor(x, levels=present_levels(x))
trim_levels.data.frame <- function(x) {
for (n in names(x))
if (is.factor(x[,n]))
x[,n] = trim_levels(x[,n])
x
}