我需要从数据框中删除“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”?谢谢你的帮助。
答案 0 :(得分:4)
在df
创建中,您没有设置stringsAsFactors = FALSE
,因此您的字符列会自动被强制转换为因子。如果您将其设置为TRUE
或使用tibble
或data_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()
在时间上稍微有点效率,但出于你的目的,我会坚持使用杰克的回答。