当 R 中只有数字时,删除空格并将值转换为数字
Remove spaces and convert values to as numeric when only numbers in R
我一直在网上寻找这个问题
与通常的发现不同的是,我有一些列,其中有数字和其他不同于纯数字的值。
比如说:
df <- data.frame('Col1' = c('421', ' 0.52', '-0.88 ', '1.2 (ref)', ' 97 '),
'Col2' = c('0.0', '0.27,0.91', '3.0', ' 10242.3', ' 94.5'))
我想从仅由数字组成的单元格中删除 spaces。不确定 0.52
等 dot
字符是否仍将其视为数字。同样在 -0.88
中 -
字符。
到目前为止我会使用
library(stringr)
# Remove spaces
df$Col1 <- str_replace_all(df$Col1, "\s+", "")
library(dplyr)
# Convert to as.numeric
df %>%
mutate_all(funs(as.numeric(as.character(.)))
但我不想只替换每个 space,例如值 1.2 (ref)
,我想保留 space。此外,不要将每个值更改为 as.numeric,仅在纯数字或 \d+\.\d+
或 \-\d+\.\d+
(正则表达式)
的情况下
此外,如果我尝试转换为 as.numeric
,数值会以某种方式发生剧烈变化,我知道这是因为值中存在 space。
提前致谢
您遇到了 akrun
和 Henrik
指出的几个问题:由于数据框中的列只能具有相同的 class,因此 1.2(ref)
值强制列为 class character
。此外,在 Col2
中有此条目:0.27,0.91
。这看起来像两个值,您需要决定如何处理它。
建议:将 Col1
分成两列。一列包含数值,另一列包含值 ref
或 NA
。这可以是字符或因子列。至于double数值:拆分成两列或决定你想保留哪个值。
在这些假设下,您的代码可能是这样的(使用 tidyverse
方法):
library(dplyr)
library(tidyr)
library(stringr)
df <- data.frame('Col1' = c('421', ' 0.52', '-0.88 ', '1.2 (ref)', ' 97 '),
'Col2' = c('0.0', '0.27,0.91', '3.0', ' 10242.3', ' 94.5'))
df <- df %>%
mutate_all(.funs = funs(str_trim)) %>% # remove leading and trailing spaces
separate(col = Col1, into = c("Value_1", "Reference"), sep = "\s|,") %>% # split into 2 columns at comma or space
separate(col = Col2, into = c("Value_2", "Value_3"), sep = "\s|,") %>% # split into 2 columns at comma or space
mutate_at(.vars = vars(starts_with("Value")), as.numeric) #convert character to numeric
此代码无法很好地扩展:如果您的数据集有很多列并且每一列都需要以不同的方式拆分,事情就会变得复杂。最好先检查您的数据集并对其进行一些质量控制。如果任何列可以包含逗号分隔值:您可以编写代码来捕获它并以统一的方式应用更正。值和文本的组合是您不应在数据集中使用的内容。
输出:
> glimpse(df)
Observations: 5
Variables: 4
$ Value_1 <dbl> 421.00, 0.52, -0.88, 1.20, 97.00
$ Reference <chr> NA, NA, NA, "(ref)", NA
$ Value_2 <dbl> 0.00, 0.27, 3.00, 10242.30, 94.50
$ Value_3 <dbl> NA, 0.91, NA, NA, NA
> df
Value_1 Reference Value_2 Value_3
1 421.00 <NA> 0.00 NA
2 0.52 <NA> 0.27 0.91
3 -0.88 <NA> 3.00 NA
4 1.20 (ref) 10242.30 NA
5 97.00 <NA> 94.50 NA
我使用 regex
构建了一个函数
library(tidyverse)
mClean <- function(strVec){
pass1 <- strVec %>%
str_trim() %>%
str_extract("(?x) # Perl-style whitespace
^[\+\-]? # An optional leading +/-
\d+ # the integer part
(\.\d+)? # A fractional part
") %>%
as.numeric()
}
我把你的数据放在小标题中 运行 它:
df <- tibble('Col1' = c('421', ' 0.52', '-0.88 ', '1.2 (ref)', ' 97 '),
'Col2' = c('0.0', '0.27,0.91', '3.0', ' 10242.3', ' 94.5')) %>%
mutate(cln1 = as.numeric(mClean(Col1)),
cln2 = as.numeric(mClean(Col2)))
df
# A tibble: 5 x 4
Col1 Col2 cln1 cln2
<chr> <chr> <dbl> <dbl>
1 421 0.0 421 0
2 " 0.52" 0.27,0.91 0.52 0.27
3 "-0.88 " 3.0 -0.88 3
4 1.2 (ref) " 10242.3" 1.2 10242.
5 " 97 " " 94.5" 97 94.5
我不确定你想用那个“0.27,0.91”做什么。分成两行?为“0.91”创建另一列?无论如何,这会将原始输入与清理后的值保持在同一行。
我一直在网上寻找这个问题
与通常的发现不同的是,我有一些列,其中有数字和其他不同于纯数字的值。
比如说:
df <- data.frame('Col1' = c('421', ' 0.52', '-0.88 ', '1.2 (ref)', ' 97 '),
'Col2' = c('0.0', '0.27,0.91', '3.0', ' 10242.3', ' 94.5'))
我想从仅由数字组成的单元格中删除 spaces。不确定 0.52
等 dot
字符是否仍将其视为数字。同样在 -0.88
中 -
字符。
到目前为止我会使用
library(stringr)
# Remove spaces
df$Col1 <- str_replace_all(df$Col1, "\s+", "")
library(dplyr)
# Convert to as.numeric
df %>%
mutate_all(funs(as.numeric(as.character(.)))
但我不想只替换每个 space,例如值 1.2 (ref)
,我想保留 space。此外,不要将每个值更改为 as.numeric,仅在纯数字或 \d+\.\d+
或 \-\d+\.\d+
(正则表达式)
此外,如果我尝试转换为 as.numeric
,数值会以某种方式发生剧烈变化,我知道这是因为值中存在 space。
提前致谢
您遇到了 akrun
和 Henrik
指出的几个问题:由于数据框中的列只能具有相同的 class,因此 1.2(ref)
值强制列为 class character
。此外,在 Col2
中有此条目:0.27,0.91
。这看起来像两个值,您需要决定如何处理它。
建议:将 Col1
分成两列。一列包含数值,另一列包含值 ref
或 NA
。这可以是字符或因子列。至于double数值:拆分成两列或决定你想保留哪个值。
在这些假设下,您的代码可能是这样的(使用 tidyverse
方法):
library(dplyr)
library(tidyr)
library(stringr)
df <- data.frame('Col1' = c('421', ' 0.52', '-0.88 ', '1.2 (ref)', ' 97 '),
'Col2' = c('0.0', '0.27,0.91', '3.0', ' 10242.3', ' 94.5'))
df <- df %>%
mutate_all(.funs = funs(str_trim)) %>% # remove leading and trailing spaces
separate(col = Col1, into = c("Value_1", "Reference"), sep = "\s|,") %>% # split into 2 columns at comma or space
separate(col = Col2, into = c("Value_2", "Value_3"), sep = "\s|,") %>% # split into 2 columns at comma or space
mutate_at(.vars = vars(starts_with("Value")), as.numeric) #convert character to numeric
此代码无法很好地扩展:如果您的数据集有很多列并且每一列都需要以不同的方式拆分,事情就会变得复杂。最好先检查您的数据集并对其进行一些质量控制。如果任何列可以包含逗号分隔值:您可以编写代码来捕获它并以统一的方式应用更正。值和文本的组合是您不应在数据集中使用的内容。
输出:
> glimpse(df)
Observations: 5
Variables: 4
$ Value_1 <dbl> 421.00, 0.52, -0.88, 1.20, 97.00
$ Reference <chr> NA, NA, NA, "(ref)", NA
$ Value_2 <dbl> 0.00, 0.27, 3.00, 10242.30, 94.50
$ Value_3 <dbl> NA, 0.91, NA, NA, NA
> df
Value_1 Reference Value_2 Value_3
1 421.00 <NA> 0.00 NA
2 0.52 <NA> 0.27 0.91
3 -0.88 <NA> 3.00 NA
4 1.20 (ref) 10242.30 NA
5 97.00 <NA> 94.50 NA
我使用 regex
library(tidyverse)
mClean <- function(strVec){
pass1 <- strVec %>%
str_trim() %>%
str_extract("(?x) # Perl-style whitespace
^[\+\-]? # An optional leading +/-
\d+ # the integer part
(\.\d+)? # A fractional part
") %>%
as.numeric()
}
我把你的数据放在小标题中 运行 它:
df <- tibble('Col1' = c('421', ' 0.52', '-0.88 ', '1.2 (ref)', ' 97 '),
'Col2' = c('0.0', '0.27,0.91', '3.0', ' 10242.3', ' 94.5')) %>%
mutate(cln1 = as.numeric(mClean(Col1)),
cln2 = as.numeric(mClean(Col2)))
df
# A tibble: 5 x 4
Col1 Col2 cln1 cln2
<chr> <chr> <dbl> <dbl>
1 421 0.0 421 0
2 " 0.52" 0.27,0.91 0.52 0.27
3 "-0.88 " 3.0 -0.88 3
4 1.2 (ref) " 10242.3" 1.2 10242.
5 " 97 " " 94.5" 97 94.5
我不确定你想用那个“0.27,0.91”做什么。分成两行?为“0.91”创建另一列?无论如何,这会将原始输入与清理后的值保持在同一行。