删除重复项时计数的R函数
R function for count number while deleting the duplicates
我有一个数据框,其中有一列包含不同的颜色。我的目的是计算此列中有多少种不同的颜色。注:"Red, 1"、"1 Red"、"Red 2"都是红色,所以以上只算一种颜色。但是,"Dark Red" 是不同的颜色
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() 进行近似匹配,但结果并不理想。我还尝试使用 distinct() 来保留所有唯一的颜色名称,但它无法处理 "Red, 1" 和 "Red, 2" 等字符串
对我来说,最困难的情况是颜色后面有一个逗号,比如“1A, Blue”或者别的什么
希望结果可以
Flower Red
Flower Yellow
Flower Green
Flower Dark Red
Flower Black
Flower White
或者,更简单
6
不需要循环,*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)
假设数据帧名为 df
那么您可以使用:
length(unique(toupper(gsub("[^a-zA-Z]", "", df$Color))))
解释:
gsub("[^a-zA-Z]", "", df$Color)
删除任何非字符的内容。所以你只剩下颜色了。
toupper
将剩余的文本大写,unique 去除重复。 length
给出向量中元素的数量。你会得到5
.
Addition: 要处理"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)
选项dplyr
library(stringr)
library(dplyr)
flowers %>%
summarise(len = n_distinct(Item, tolower(str_remove(Color, "[^A-Za-z]+"))))
# len
#1 5
数据
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))
另一个使用 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
我有一个数据框,其中有一列包含不同的颜色。我的目的是计算此列中有多少种不同的颜色。注:"Red, 1"、"1 Red"、"Red 2"都是红色,所以以上只算一种颜色。但是,"Dark Red" 是不同的颜色
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() 进行近似匹配,但结果并不理想。我还尝试使用 distinct() 来保留所有唯一的颜色名称,但它无法处理 "Red, 1" 和 "Red, 2" 等字符串 对我来说,最困难的情况是颜色后面有一个逗号,比如“1A, Blue”或者别的什么
希望结果可以
Flower Red
Flower Yellow
Flower Green
Flower Dark Red
Flower Black
Flower White
或者,更简单
6
不需要循环,*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)
假设数据帧名为 df
那么您可以使用:
length(unique(toupper(gsub("[^a-zA-Z]", "", df$Color))))
解释:
gsub("[^a-zA-Z]", "", df$Color)
删除任何非字符的内容。所以你只剩下颜色了。
toupper
将剩余的文本大写,unique 去除重复。 length
给出向量中元素的数量。你会得到5
.
Addition: 要处理"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)
选项dplyr
library(stringr)
library(dplyr)
flowers %>%
summarise(len = n_distinct(Item, tolower(str_remove(Color, "[^A-Za-z]+"))))
# len
#1 5
数据
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))
另一个使用 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