我是处理R和使用字符串的初学者。 我一直在尝试从数据中删除时间段,但不幸的是我找不到解决方案。
这是我正在数据框df
中处理的数据:
df <- read.table(text = " n mesAno receita
97 1/2009 3.812.819.062,06
98 2/2009 4.039.362.599,36
99 3/2009 3.652.885.587,18
100 4/2009 3.460.247.960,02
101 5/2009 3.465.677.403,12
102 6/2009 3.131.903.622,55
103 7/2009 3.204.983.361,46
104 8/2009 3.811.786.009,24
105 9/2009 3.180.864.095,05
106 10/2009 3.352.535.553,88
107 11/2009 5.214.148.756,95
108 12/2009 4.491.795.201,50
109 1/2010 4.333.557.619,30
110 2/2010 4.808.488.277,86
111 3/2010 4.039.347.179,81
112 4/2010 3.867.676.530,69
113 5/2010 6.356.164.873,94
114 6/2010 3.961.793.391,19
115 7/2010 3797656130.81
116 8/2010 4709949715.37
117 9/2010 4047436592.12
118 10/2010 3923484635.28
119 11/2010 4821729985.03
120 12/2010 5024757038.22",
header = TRUE,
stringsAsFactors = TRUE)
我的目标是将receita
列转换为数值,因为它被存储为因子。但是,应用as.numeric(as.factor(x))
之类的转换函数在97:114的间隔中不起作用(它强制为NA)。
我认为这是因为此列中的分隔十亿/百万/千位的时期。
仅当我在115:120中使用3812819062.06
之类的内容时,上述转换功能才有效。
我尝试对数据集进行变异,添加另一列并进行建模。 我真的不知道我在做什么是否很好,但是我也尝试将异常数字提取到变量中,然后将sub / gsub应用于变量,但没有成功。
是否有一些直接的方法可以执行此操作,也就是说,指示它删除“。”的前两次出现。然后用'。'替换逗号?
我非常有信心我需要的功能是gsub
,但是我很难找到正确的用法。任何帮助将不胜感激。
编辑:我使用dplyr::mutate()
的方法。丑陋但行得通。
df <- df %>%
mutate(receita_temp = receita) %>%
mutate(dot_count = str_count(receita, '\\.')) %>%
mutate(receita_temp = ifelse(dot_count == 3,
gsub('\\.', '', as.factor(receita_temp)),
gsub('\\,', '.',as.factor(receita_temp))
)) %>%
mutate(receita_temp = ifelse(dot_count == 3,
gsub('\\,', '.',as.factor(receita_temp)),
receita_temp)) %>%
select(-c(dot_count, receita)) %>%
rename(., receita = receita_temp)
答案 0 :(得分:2)
我正在使用正则表达式和一些stringr
函数来删除除两个数字和字符串结尾之外的所有句点。这样,3.811.786.009,24
中表示分隔的句段就被删除,而4821729985.03
中表示小数点起始的句段则没有。使用str_remove_all
而不是str_remove
可使我不必担心重复删除匹配项或扩展性如何。然后,用句号替换其余的逗号,并使其成为数字。
library(tidyverse)
df2 <- df %>%
mutate(receita = str_remove_all(receita, "\\.(?!\\d{2,}$)") %>%
str_replace_all(",", ".") %>%
as.numeric())
print(head(df2), digits = 12)
#> n mesAno receita
#> 1 97 1/2009 3812819062.06
#> 2 98 2/2009 4039362599.36
#> 3 99 3/2009 3652885587.18
#> 4 100 4/2009 3460247960.02
#> 5 101 5/2009 3465677403.12
#> 6 102 6/2009 3131903622.55
由reprex package(v0.2.0)于2018-09-04创建。
答案 1 :(得分:1)
df$num <- as.numeric(sapply(as.character(si), function(x) gsub("\\,","\\.",ifelse(grepl("\\,", x), gsub("\\.","",x),x))))
应该可以解决问题。
首先,该函数搜索带有“,”的行,删除“”。在这些行中,最后将所有出现的“,”转换为“。”,以便可以毫无问题地将其转换为数字。
使用print(df$num, digits = 12)
查看带有两位小数的数据。
答案 2 :(得分:1)
您可以使用以下内容: 首先创建一个将用于替换的函数:
repl = function(x)setNames(c("","."),c(".",","))[x]
此函数接受"."
或","
并分别返回""
或'.'
现在使用此功能替换
stringr::str_replace_all(as.character(df[,3]), "[.](?!\\d+$)|,", repl)
[1] "3812819062.06" "4039362599.36" "3652885587.18" "3460247960.02" "3465677403.12" "3131903622.55"
[7] "3204983361.46" "3811786009.24" "3180864095.05" "3352535553.88" "5214148756.95" "4491795201.50"
[13] "4333557619.30" "4808488277.86" "4039347179.81" "3867676530.69" "6356164873.94" "3961793391.19"
[19] "3797656130.81" "4709949715.37" "4047436592.12" "3923484635.28" "4821729985.03" "5024757038.22"
您当然可以做剩下的事情。即致电as.numeric()
等
要在基数R中执行此操作:
sub(',','.',gsub('[.](?!\\d+$)','',as.character(df[,3]),perl=T))
或者如果您知道数据中.
和,
的确切数量,则可以
a = as.character(df[,3])
regmatches(a,gregexpr('[.](?!\\d+$)|,',df[,3],perl = T)) = list(c("","","","."))
a