#r
#r
Вопрос:
Вот фрейм данных:
vegetables <- c("carrots", "carrots", "carrots", "carrots", "carrots")
animals <- c("cats", "dogs", "dogs", "fish", "cats")
df <- data.frame(vegetables, animals)
Выглядит так:
> df
vegetables animals
1 carrots cats
2 carrots dogs
3 carrots dogs
4 carrots fish
5 carrots cats
Если бы я хотел удалить строки, в которых частота уровней была ниже, например, 2 (так что ловите рыбу в примере df), затем удалите эту строку:
for ( i in names(df) ) {
df <- subset(df, with(df, df[,i] %in% names(which(table(df[,i]) >= 2))))
}
> df
vegetables animals
1 carrots cats
2 carrots dogs
3 carrots dogs
5 carrots cats
Но что, если я не хочу удалять наблюдение, а вместо этого заменяю fish на «bla».
Как бы я это сделал?
Желаемый результат:
> df
vegetables animals
1 carrots cats
2 carrots dogs
3 carrots dogs
4 carrots bla
5 carrots cats
Ответ №1:
Не уверен, важны ли уровни переменной, если нет, вы можете сделать следующее с stringsAsFactors=FALSE
помощью опции as в data.frame
vegetables <- c("carrots", "carrots", "carrots", "carrots", "carrots")
animals <- c("cats", "dogs", "dogs", "fish", "cats")
DF <- data.frame(vegetables, animals,stringsAsFactors=FALSE)
threshold = 2
DF$animals[ DF$animals == names(which(table(DF$animals) < threshold)) ] = "foo"
DF
# vegetables animals
#1 carrots cats
#2 carrots dogs
#3 carrots dogs
#4 carrots foo
#5 carrots cats
Комментарии:
1. Спасибо за ответ. Я пытался использовать его в моем реальном фрейме данных, но stringsAsFactors=FALSE вызывал у меня проблемы
Ответ №2:
Вы можете просто обновить уровни, используя таблицу для индексации, какие из них нужно изменить:
levels(df$animals)[table(df$animals) < 2] <- 'bla'
df
## vegetables animals
## 1 carrots cats
## 2 carrots dogs
## 3 carrots dogs
## 4 carrots bla
## 5 carrots cats
Комментарии:
1. вау! Это тоже работает и является самым простым. С одной стороны, я хочу быть лояльным к @akrun и поддерживать его ответ, поскольку он был действительно терпелив и очень помог мне в комментариях (теперь удалены). С другой стороны, это самый простой и, по-видимому, лучший вариант
2. Это так здорово! Так элегантно!
Ответ №3:
Мы можем использовать data.table
library(data.table)
setDT(df)[df[, .I[.N > 1], by = .(vegetables, animals)]$V1]
Если мы хотим заменить низкочастотный элемент в каждом столбце на ‘bla’
threshold <- 1
df[] <- lapply(df, as.character)
setDT(df)
for(j in seq_along(df)){
df[, N := .N, c(names(df)[j])][N == threshold, names(df)[j] := "bla"][, N := NULL][]
}
Комментарии:
1. @DougFir Вы хотите сказать, что хотите иметь «bla» во всех столбцах с меньшим количеством элементов? В этом случае «овощи» имеют только один элемент. Итак, вам может понадобиться пороговое значение