如何在整个数据帧中应用正则表达式而不将所有列都设置为字符

时间:2018-04-20 16:40:59

标签: r regex dplyr

我需要从数据框中删除“Z”:

df <- data.frame(Mineral = c("Zfeldspar", "Zgranite", "ZSilica"),
                Confidence = c("ZLow", "High", "Med"),
                Coverage = c("sub", "sub", "super"),
                Aspect = c("ZPos", "ZUnd", "Neg"),
                Pile1 = c(70, 88, 95),
                Pile2 = c(62,41,81))

我使用了tidyverse:

library(tidyverse)

df <- mutate_all(df, funs(str_replace_all(., "Z", ""))) %>%
      mutate(PileAvg = mean(Pile1 + Pile2))

但我收到错误

Error in mutate_impl(.data, dots) : 
  Evaluation error: non-numeric argument to binary operator.

我做过调查,这是因为桩柱现在是字符,而不是数字。如何在不更改所有内容的情况下使用正则表达式删除“Z”?谢谢你的帮助。

2 个答案:

答案 0 :(得分:4)

df创建中,您没有设置stringsAsFactors = FALSE,因此您的字符列会自动被强制转换为因子。如果您将其设置为TRUE或使用tibbledata_frame,您将获得字符列。

这是您使用mutate_if而不是mutate_all的地方。通过构造要在mutate_if中使用的谓词函数,这是一种适用于因子和字符的方法。

df <- data.frame(Mineral = c("Zfeldspar", "Zgranite", "ZSilica"),
                 Confidence = c("ZLow", "High", "Med"),
                 Coverage = c("sub", "sub", "super"),
                 Aspect = c("ZPos", "ZUnd", "Neg"),
                 Pile1 = c(70, 88, 95),
                 Pile2 = c(62,41,81))

is_character_factor <- function(x){

  is.character(x)|is.factor(x)

}

mutate_if(df, is_character_factor, funs(str_replace(., "Z", ""))) %>%
  mutate(PileAvg = mean(Pile1 + Pile2))

答案 1 :(得分:1)

@Jake Kaupps的答案非常好,但这是另一种使用modify_if purrr的方法。

我还注意到,您似乎正在尝试计算行均值,在这种情况下使用means(Pile1 + Pile2)将无效。您可以使用rowwise()调用原始数据框来逐行计算均值。

df <- modify_if(rowwise(df), is.character, function (x) str_replace_all(x, "Z", "")) %>%
      mutate(PileAvg = mean(c(Pile1,Pile2)))

# Output
# A tibble: 3 x 7
  Mineral  Confidence Coverage Aspect Pile1 Pile2 PileAvg
  <chr>    <chr>      <chr>    <chr>  <dbl> <dbl>   <dbl>
1 feldspar Low        sub      Pos      70.   62.    66.0
2 granite  High       sub      Und      88.   41.    64.5
3 Silica   Med        super    Neg      95.   81.    88.0

modify_if()在时间上稍微有点效率,但出于你的目的,我会坚持使用杰克的回答。