是否有 R 函数可以清理字符格式的杂乱工资?
Is there an R function to clean messy salaries in character format?
我有一列乱七八糟的工资数据。想知道有没有专门做清理这类乱码数据功能的包。我的数据如下:
data.frame(salary = c("40,000-60,000", "40-80K", "0,000",
"/hr", "Between -80/hour", "0k",
"50-60,000 a year", "90"))
#> salary
#> 1 40,000-60,000
#> 2 40-80K
#> 3 0,000
#> 4 /hr
#> 5 Between -80/hour
#> 6 0k
#> 7 50-60,000 a year
#> 8 90
由 reprex package (v0.3.0)
于 2020-12-16 创建
我希望干净的列是年度级别的数字。我知道如何手动清理此列,我只是想知道是否有任何其他软件包可以提供帮助(readr::parse_number()
除外)
预期输出如下:
#> output
#> 1 50000
#> 2 60000
#> 3 100000
#> 4 145600
#> 5 150800
#> 6 100000
#> 7 55000
#> 8 90000
一个选项是创建一个仅包含数字和 -
的列 'salary1',然后 separate
通过 -
、[=15] 将其分为两列=] 这些列的值,基于原始列中的子字符串匹配,即 K|k
或 hr|hour
即,将它们乘以 1000 (K|k
) 或每小时,基于一年的小时数,使用 case_when
并获得这些列的 rowMeans
library(dplyr)
library(stringr)
library(tidyr)
df1 %>%
mutate(salary1 = str_remove_all(salary, '[^0-9-]+')) %>%
separate(salary1, into = c('salary1', 'salary2'),
convert = TRUE, extra = 'drop') %>%
mutate(across(c(salary1, salary2),
~ case_when(str_detect(salary, "[Kk]") ~ . * 1000,
str_detect(salary, 'hr|hour') ~ . * 40 * 4 * 12,
nchar(.) < 5 ~ as.numeric(str_pad(., pad = '0',
side = 'right', width = 5)),
TRUE ~ as.numeric(.)))) %>%
transmute(output = rowMeans(select(., salary1, salary2), na.rm = TRUE))
-输出
# output
#1 50000
#2 60000
#3 100000
#4 134400
#5 139200
#6 100000
#7 55000
#8 90000
您可以先尝试以下几个步骤。
我定义了两个函数:一个用三个零替换 k
或 K
。
如果一个数字以千为单位表示而另一个不是,则另一个添加前导零。
rem_k <- function(x) {
sub("(\d)[kK]", "\1,000", x)
}
add_zero <- function(x) {
ifelse(grepl("[1-9]0\-\d[0,]{2,}", x), sub("([1-9]0)(\-\d[0,]{2,})", "\1,000\2", x), x)
}
最后,我删除了所有非必要字符:
df %>%
mutate(salary2 = gsub("[^0-9,\-]", "", add_zero(rem_k(salary))))
salary salary2
1 40,000-60,000 40,000-60,000
2 40-80K 40,000-80,000
3 0,000 100,000
4 /hr 70
5 Between -80/hour 65-80
6 0k 100,000
7 50-60,000 a year 50,000-60,000
8 90 90
我有一列乱七八糟的工资数据。想知道有没有专门做清理这类乱码数据功能的包。我的数据如下:
data.frame(salary = c("40,000-60,000", "40-80K", "0,000",
"/hr", "Between -80/hour", "0k",
"50-60,000 a year", "90"))
#> salary
#> 1 40,000-60,000
#> 2 40-80K
#> 3 0,000
#> 4 /hr
#> 5 Between -80/hour
#> 6 0k
#> 7 50-60,000 a year
#> 8 90
由 reprex package (v0.3.0)
于 2020-12-16 创建我希望干净的列是年度级别的数字。我知道如何手动清理此列,我只是想知道是否有任何其他软件包可以提供帮助(readr::parse_number()
除外)
预期输出如下:
#> output
#> 1 50000
#> 2 60000
#> 3 100000
#> 4 145600
#> 5 150800
#> 6 100000
#> 7 55000
#> 8 90000
一个选项是创建一个仅包含数字和 -
的列 'salary1',然后 separate
通过 -
、[=15] 将其分为两列=] 这些列的值,基于原始列中的子字符串匹配,即 K|k
或 hr|hour
即,将它们乘以 1000 (K|k
) 或每小时,基于一年的小时数,使用 case_when
并获得这些列的 rowMeans
library(dplyr)
library(stringr)
library(tidyr)
df1 %>%
mutate(salary1 = str_remove_all(salary, '[^0-9-]+')) %>%
separate(salary1, into = c('salary1', 'salary2'),
convert = TRUE, extra = 'drop') %>%
mutate(across(c(salary1, salary2),
~ case_when(str_detect(salary, "[Kk]") ~ . * 1000,
str_detect(salary, 'hr|hour') ~ . * 40 * 4 * 12,
nchar(.) < 5 ~ as.numeric(str_pad(., pad = '0',
side = 'right', width = 5)),
TRUE ~ as.numeric(.)))) %>%
transmute(output = rowMeans(select(., salary1, salary2), na.rm = TRUE))
-输出
# output
#1 50000
#2 60000
#3 100000
#4 134400
#5 139200
#6 100000
#7 55000
#8 90000
您可以先尝试以下几个步骤。
我定义了两个函数:一个用三个零替换 k
或 K
。
如果一个数字以千为单位表示而另一个不是,则另一个添加前导零。
rem_k <- function(x) {
sub("(\d)[kK]", "\1,000", x)
}
add_zero <- function(x) {
ifelse(grepl("[1-9]0\-\d[0,]{2,}", x), sub("([1-9]0)(\-\d[0,]{2,})", "\1,000\2", x), x)
}
最后,我删除了所有非必要字符:
df %>%
mutate(salary2 = gsub("[^0-9,\-]", "", add_zero(rem_k(salary))))
salary salary2
1 40,000-60,000 40,000-60,000
2 40-80K 40,000-80,000
3 0,000 100,000
4 /hr 70
5 Between -80/hour 65-80
6 0k 100,000
7 50-60,000 a year 50,000-60,000
8 90 90