从R中的单个列中提取多个变量
我正在处理一个数据清理问题,我被卡住了。我已经开始接收以下格式的csv文件,我需要先清理它,然后才能进行任何分析。有几个这样的列,每个单元格中可能有几百个需要提取的变量从R中的单个列中提取多个变量,r,dplyr,tidyr,R,Dplyr,Tidyr,我正在处理一个数据清理问题,我被卡住了。我已经开始接收以下格式的csv文件,我需要先清理它,然后才能进行任何分析。有几个这样的列,每个单元格中可能有几百个需要提取的变量 Original <- structure(list(CustNum = c(0, 1), Sales = c("[1000, 345, Zero, 56]", "[987, 879, 325, 4568]"),
Original <- structure(list(CustNum = c(0, 1),
Sales = c("[1000, 345, Zero, 56]", "[987, 879, 325, 4568]"),
Amounts = c("[10, 2, 0, 98]", "[57, 25, 52, 75]"),
Number = c("['1', '2', '3', '4']", "['4', '3', '2', '1']"),
Identifier = c("A", "B")),
row.names = c(NA, -2L),
class = c("tbl_df", "tbl", "data.frame"))
在Excel中的Power Query中进行清理很容易,但我想找到一种在R中进行清理的方法,这样我就不必使用多种不同的工具。有人能告诉我怎么做吗?我建议采用这种方法,首先将
原始的
数据重塑为长数据,然后按sep=','分隔行。之后,您将清理变量以删除一些特殊字符。因此,您可以按组创建id变量,以便在所需的中将数据转换为所需的宽度:
library(tidyverse)
#Reshape
Original %>%
pivot_longer(cols = -c(CustNum,Identifier)) %>%
separate_rows(value,sep = ',') %>%
mutate(value=trimws(gsub("[[:punct:]]", " ", value))) %>%
group_by(name) %>% mutate(id=1:n()) %>%
pivot_wider(names_from = name,values_from=value) %>%
ungroup() %>%
select(-id)
输出:
# A tibble: 8 x 5
CustNum Identifier Sales Amounts Number
<dbl> <chr> <chr> <chr> <chr>
1 0 A 1000 10 1
2 0 A 345 2 2
3 0 A Zero 0 3
4 0 A 56 98 4
5 1 B 987 57 4
6 1 B 879 25 3
7 1 B 325 52 2
8 1 B 4568 75 1
#一个tible:8 x 5
CustNum标识符销售金额编号
10 A 1000 10 1
20A34522
30A03
40A 5698 4
51B987574
61B879253
7 1 B 325 52 2
81B4568751
我建议采用这种方法,首先将原始
数据重塑为long,然后通过sep=','
分隔行。之后,您将清理变量以删除一些特殊字符。因此,您可以按组创建id变量,以便在所需的中将数据转换为所需的宽度:
library(tidyverse)
#Reshape
Original %>%
pivot_longer(cols = -c(CustNum,Identifier)) %>%
separate_rows(value,sep = ',') %>%
mutate(value=trimws(gsub("[[:punct:]]", " ", value))) %>%
group_by(name) %>% mutate(id=1:n()) %>%
pivot_wider(names_from = name,values_from=value) %>%
ungroup() %>%
select(-id)
输出:
# A tibble: 8 x 5
CustNum Identifier Sales Amounts Number
<dbl> <chr> <chr> <chr> <chr>
1 0 A 1000 10 1
2 0 A 345 2 2
3 0 A Zero 0 3
4 0 A 56 98 4
5 1 B 987 57 4
6 1 B 879 25 3
7 1 B 325 52 2
8 1 B 4568 75 1
#一个tible:8 x 5
CustNum标识符销售金额编号
10 A 1000 10 1
20A34522
30A03
40A 5698 4
51B987574
61B879253
7 1 B 325 52 2
81B4568751
试试这个:
library(dplyr) # must be version >= 1.0.0
library(stringr)
Original %>%
mutate(across(everything(), str_remove_all, pattern = "\\[|\\]|\\'")) %>%
mutate(across(everything(), str_split, pattern = ",")) %>%
tidyr::unnest(everything()) %>%
mutate(across(everything(), str_trim)) %>%
mutate(across(c(CustNum, Amounts, Number), as.numeric))
#一个tible:8 x 5
CustNum销售金额编号标识符
101000101A
23034522A
30003A
4056984A
51987574B
61879253B
71325522B
814568751B
基本上:
- 删除
[
]
'
- 按
,
- 取消列表
- 修剪掉不必要的空间
- 必要时设置为数字
试试这个:
library(dplyr) # must be version >= 1.0.0
library(stringr)
Original %>%
mutate(across(everything(), str_remove_all, pattern = "\\[|\\]|\\'")) %>%
mutate(across(everything(), str_split, pattern = ",")) %>%
tidyr::unnest(everything()) %>%
mutate(across(everything(), str_trim)) %>%
mutate(across(c(CustNum, Amounts, Number), as.numeric))
#一个tible:8 x 5
CustNum销售金额编号标识符
101000101A
23034522A
30003A
4056984A
51987574B
61879253B
71325522B
814568751B
基本上:
- 删除
[
]
'
- 按
,
- 取消列表
- 修剪掉不必要的空间
- 必要时设置为数字
您可以尝试这种方法
library(tidyverse)
library(stringr)
Original2 <- Original %>%
mutate_at(vars(Sales, Amounts, Number), ~str_replace_all(., "\\[|\\'|\\]|\\s", "")) %>%
separate_rows(c("Sales", "Amounts", "Number"), sep = ",")
# CustNum Sales Amounts Number Identifier
# <dbl> <chr> <chr> <chr> <chr>
# 1 0 1000 10 1 A
# 2 0 345 2 2 A
# 3 0 Zero 0 3 A
# 4 0 56 98 4 A
# 5 1 987 57 4 B
# 6 1 879 25 3 B
# 7 1 325 52 2 B
# 8 1 4568 75 1 B
库(tidyverse)
图书馆(stringr)
原始2%
在(变量(销售额、金额、数量)处进行变异,~str\u替换所有(,“\\[\\\'\\\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
单独的行(c(“销售额”、“金额”、“数量”),sep=“,”)
#CustNum销售金额编号标识符
#
#101000101A
#23034522A
#30003A
#4056984A
#51987574B
#61879253B
#71325522B
#814568751B
这里我们替换[,”和空格,然后使用separate_rows()
fromtidyr
包来分隔行。实现我们的目标需要两个步骤。您可以尝试这种方法
library(tidyverse)
library(stringr)
Original2 <- Original %>%
mutate_at(vars(Sales, Amounts, Number), ~str_replace_all(., "\\[|\\'|\\]|\\s", "")) %>%
separate_rows(c("Sales", "Amounts", "Number"), sep = ",")
# CustNum Sales Amounts Number Identifier
# <dbl> <chr> <chr> <chr> <chr>
# 1 0 1000 10 1 A
# 2 0 345 2 2 A
# 3 0 Zero 0 3 A
# 4 0 56 98 4 A
# 5 1 987 57 4 B
# 6 1 879 25 3 B
# 7 1 325 52 2 B
# 8 1 4568 75 1 B
库(tidyverse)
图书馆(stringr)
原始2%
在(变量(销售额、金额、数量)处进行变异,~str\u替换所有(,“\\[\\\'\\\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
单独的行(c(“销售额”、“金额”、“数量”),sep=“,”)
#CustNum销售金额编号标识符
#
#101000101A
#23034522A
#30003A
#4056984A
#51987574B
#61879253B
#71325522B
#814568751B
在这里,我们替换[,”和空格,然后使用separate_rows()
fromtidyr
包来分隔行。实现我们的目标需要两个步骤。这是一个非常酷的解决方案!!做得很好!但是,我认为您应该使用mutate(跨(…)来更改mutate_at(…)
)
因为它现在被取代了。比如:变异(跨越(c)(销售额、金额、数字),str\u删除所有,\\[\\\\\\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\(销售额、金额、数字),str\u remove\u all,“\\[\\\\\\\\\\\\]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\”)%>%