Функция R для подсчета числа при удалении дубликатов - PullRequest
2 голосов
/ 29 сентября 2019

У меня есть датафрейм, в котором есть столбец, содержащий разные цвета. Моя цель - подсчитать, сколько разных цветов в этом столбце. Примечание: «Красный, 1», «1 Красный», «Красный 2» - это красный, поэтому все вышеперечисленное считается только одним цветом. однако «Темно-красный» - это другой цвет

Item               Color
Flower             Red 1
Flower             Yellow 1
Flower             Red, 1
Flower             Red 2
Flower             2 red
Flower             Green, 1
Flower             Dark Red 1
Flower             Green, 2
Flower             Black
Flower             White 1
Flower             1A, Green

Поскольку в этом столбце структуры названий цветов не идентичны. Следовательно, я не могу просто использовать sub (), чтобы удалить все после первого слова и посчитать число. Я пытался использовать sapply (apply ()) или grep () для приблизительного соответствия, но результат не настолько идеален. Я также попытался в методе perfect () оставить все уникальные названия цветов, но он не справляется со строками, такими как «Red, 1» и «Red, 2». Для меня самая сложная ситуация - это цвет после запятой, такой как «1A, Blue "или что-то еще

Я надеюсь, что результат может быть

Flower    Red
Flower    Yellow
Flower    Green
Flower    Dark Red
Flower    Black
Flower    White

Или, проще

6

Ответы [ 4 ]

2 голосов
/ 30 сентября 2019

Нет необходимости в циклах, *apply или других, соответствующее регулярное выражение выполнит большую часть работы.

x <- tolower(gsub("[^[:alpha:]]", "", flowers$Color))
unique(x)
#[1] "red"    "yellow" "green"  "black"  "white" 

length(unique(x))
#[1] 5

Данные.

flowers <- read.table(text = "
Item               Color
Flower             'Red 1'
Flower             'Yellow 1'
Flower             'Red, 1'
Flower             'Red 2'
Flower             '2 red'
Flower             'Green, 1'
Flower             'Green, 2'
Flower             'Black'
Flower             'White 1'
", header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 30 сентября 2019

Другое решение с использованием пакета stringr и colors().

library(readr)
library(stringr)

A <- read_table("Item               Color
Flower             Red 1
Flower             Yellow 1
Flower             Red, 1
Flower             Red 2
Flower             2 red
Flower             Green, 1
Flower             Green, 2
Flower             Black
Flower             White 1")

A$Color <- casefold(A$Color, upper = TRUE)
colors_considered <- casefold(colors(), upper = TRUE)

bb <- as.data.frame(A$Color)
BB <- apply(bb,1,function(x) str_extract(x,colors_considered))

CC <- BB[!is.na(BB)]

output <- data.frame(item = A$Item,color = CC) %>%
 unique()

Вывод:

> output
    item  color
1 Flower    RED
2 Flower YELLOW
6 Flower  GREEN
8 Flower  BLACK
9 Flower  WHITE
0 голосов
/ 30 сентября 2019

Опция с dplyr

library(stringr)
library(dplyr)
flowers %>% 
    summarise(len = n_distinct(Item,  tolower(str_remove(Color, "[^A-Za-z]+"))))
#  len
#1   5

data

  flowers <- structure(list(Item = c("Flower", "Flower", "Flower", "Flower", 
"Flower", "Flower", "Flower", "Flower", "Flower"), Color = c("Red 1", 
"Yellow 1", "Red, 1", "Red 2", "2 red", "Green, 1", "Green, 2", 
"Black", "White 1")), class = "data.frame", row.names = c(NA, 
-9L))
0 голосов
/ 30 сентября 2019

Скажем, датафрейм называется df, тогда вы можете использовать:

length(unique(toupper(gsub("[^a-zA-Z]", "", df$Color))))

Объяснение:

gsub("[^a-zA-Z]", "", df$Color) удаляет все, что не является символом. Таким образом, у вас остаются только цвета.

toupper делает капитализированный оставшийся текст, а уникальный удаляет дубликаты. length дает вам количество элементов в векторе. Вы получите 5.

Сложение : Чтобы обработать регистр "Red, 1A", вы можете удалить все после ',' и затем использовать вышеуказанное решение. Например:

x <- gsub(",.*$", "", df$Color) ## removes a comma and anything that follows

length(unique(toupper(gsub("[^a-zA-Z]", "", x)))) ## removes all but letters

Альтернатива для удаления всего после запятой: вы можете удалить любую буквенную цифру, такую ​​как "1A "или" A1 "с:

x <- gsub("[a-zA-Z]*[0-9][a-zA-Z]*", "", df$Color)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...