R:在管道中组合几个 gsub() 函数

R: combine several gsub() function in a pipe

为了清理一些杂乱的数据,我想开始使用管道 %>%,但如果 gsub() 不在管道的开头,我将无法使 R 代码工作,应该会晚一些(注:本题与正确导入无关,与数据清洗有关)

简单示例:

df <- cbind.data.frame(A= c("2.187,78 ", "5.491,28 ", "7.000,32 "), B = c("A","B","C"))

A 列包含字符(在本例中为数字,但也可以是字符串)需要清理。 步骤为

df$D <- gsub("\.","",df$A)
df$D <- str_trim(df$D) 
df$D <- as.numeric(gsub(",", ".",df$D))

一个人很容易就能用管道输送这个

df$D  <-  gsub("\.","",df$A) %>%
          str_trim() %>%
          as.numeric(gsub(",", ".")) %>%

问题出在第二个 gsub,因为它要求输入 .... 实际上是上一行的结果。

拜托,谁能解释一下如何在管道中进一步使用像 gsub() 这样的函数? 非常感谢!

系统:R 3.2.3,Windows

试试这个:

library(stringr)

df$D <- df$A %>%
  { gsub("\.","", .) } %>%
  str_trim() %>%
  { as.numeric(gsub(",", ".", .)) }

使用管道,你的数据作为 first 参数传递给下一个函数,所以如果你想在其他地方使用它,你需要将下一行换行在 {} 并使用 . 作为数据 "marker".

问题是输入管道的参数必须是参数列表中的第一个。但是 gsub() 不是这样,因为 x 是第三个。一个(冗长的)解决方法可能是:

df$A %>% 
  gsub(pattern = "\.", replacement="") %>%
  str_trim() %>%
  gsub(patter = ",", replacement = ".") %>%
  as.numeric

通常将管道作为一个整体应用于数据帧,就像这样返回清理后的数据帧。函数式编程的思想是对象是不可变的,不会就地改变,而是生成新的对象。

library(dplyr)

df %>%
   mutate(C = gsub("\.", "", A)) %>%
   mutate(C = gsub(",", ".", C)) %>%
   mutate(C = as.numeric(C))

另请注意,这些替代方案有效:

df %>% mutate(C = gsub("\.", "", A), C = gsub(",", ".", C), C = as.numeric(C))


df %>% mutate(C = read.table(text = gsub("[.]", "", A), dec = ",")[[1]])


df %>% mutate(C = type.convert(gsub("[.]", "", A), dec = ","))

对于这个特定的例子,type.convert 似乎是最合适的,因为它在较高的层次上简洁地表达了我们打算做什么。相比之下,gsub/as.numeric 解决方案似乎级别太低且冗长,而 read.table 将转换添加到 data.frame,我们需要撤消它使其级别太高。

您可以使用包 stringr 中的 str_replace(string, pattern, replacement) 作为 drop-in 替代 gsub。 stringr 函数遵循一种简洁的方法,其中字符串/字符向量是第一个参数。

c("hello", "hi") %>% str_replace_all("[aeiou]", "x")

有关 stringr 的合理命名和定义函数的更多信息,请参阅 Introduction to stringr 以替代 R 的默认字符串函数。