在管道 R 工作流中向大多数 data.frame 变量名称添加前缀或后缀



我想在 data.frame 中的大多数变量名称中添加后缀或前缀,通常是在它们以某种方式全部转换之后和执行连接之前。 我没有办法在不破坏我的管道的情况下做到这一点。

例如,使用此数据:

library(dplyr)
set.seed(1)
dat14 <- data.frame(ID = 1:10, speed = runif(10), power = rpois(10, 1),
                    force = rexp(10), class = rep(c("a", "b"),5))

我想得到这个结果(注意变量名称):

  class speed_mean_2014 power_mean_2014 force_mean_2014
1     a       0.5572500             0.8       0.5519802
2     b       0.2850798             0.6       1.0888116

我目前的方法是:

means14 <- dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.)))  
names(means14)[2:length(names(means14))] <- paste0(names(means14)[2:length(names(means14))], "_mean_2014")

除了打破我的管道的笨拙的最后一行之外,还有其他选择吗? 我已经查看了select()rename(),但不想显式指定每个变量名称,因为我通常希望重命名除单个变量之外的所有变量,并且可能具有比此示例中更广泛的 data.frame。

我正在想象一个接近这个虚构函数的最终管道命令:

appendname(cols = 2:n, str = "_mean_2014", placement = "suffix")

我所知,这并不存在。

你可以将函数传递给rename_at,所以

 means14 <- dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_all(funs(mean(.))) %>% 
  rename_at(vars(-class),function(x) paste0(x,"_2014"))

在发布此问题后进行了其他实验,我发现setNames函数将在返回 data.frame 时与管道一起使用:

dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) %>%
  setNames(c(names(.)[1], paste0(names(.)[-1],"_mean_2014"))) 
  class speed_mean_2014 power_mean_2014 force_mean_2014
1     a       0.5572500             0.8       0.5519802
2     b       0.2850798             0.6       1.0888116

这更快一些,但不完全是你想要的:

dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) -> means14 
names(means14)[-1] %<>% paste0("_mean_2014")

如果您之前没有使用过%<>%-运算符,请务必查看此链接,这是一个超级有用的工具。

您还可以使用它来重新计算或舍入某些列,例如 这个 df$meancolumn %<>% round() ,等等,它经常出现,只是为您节省了大量写作

截至 2017 年 2 月,您可以使用 dplyr 命令 rename_(...) 执行此操作。

在本例中,您可以这样做。

dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) %>%
  rename_(names(.)[-1], paste0(names(.)[-1],"_mean_2014"))) 

这与set_names的答案非常相似,但也适用于 tibbles!

这更像是一种退步,但您可能会考虑重塑数据,以便同时将函数应用于多个年份。这将保持整洁。如果要最终比较不同的年份,将年份作为数据帧中的单独变量,而不是将年份存储在名称中可能是有意义的。您应该能够使用summarise_来获取mean_year行为。请参阅 http://cran.r-project.org/web/packages/dplyr/vignettes/nse.html

library(dplyr)
library(tidyr)
set.seed(1)
dat14 <- data.frame(ID = 1:10, speed = runif(10), power = rpois(10, 1),
                    force = rexp(10), class = rep(c("a", "b"),5))
dat14 %>% 
  gather(variable, value, -ID, -class) %>% 
  mutate(year = 2014) %>% 
  group_by(class, year, variable)%>% 
  summarise(mean = mean(value))`

虽然使用 setNames() ist 的 Sam Firkes 解决方案肯定是唯一保持不间断管道的解决方案,但它不适用于 dplyr 中的tbl对象,因为通常的基本 R 命名函数的方法无法访问列名。这里有一个函数,你也可以在带有tbl对象的管道中使用,这要归功于 hrbrmstr 的这个解决方案。它在指定的列索引处添加预定义的前缀和后缀。默认值为所有列。

tbl.renamer <- function(tbl,prefix="x",suffix=NULL,index=seq_along(tbl_vars(tbl))){
  newnames <- tbl_vars(tbl) # Get old variable names
  names(newnames) <- newnames
  names(newnames)[index] <- paste0(prefix,".",newnames,suffix)[index] # create a named vector for .dots
  rename_(tbl,.dots=newnames) # rename the variables
}

示例用法(假设auth_users beeing tbl_sql对象):

auth_user %>% tbl_vars
tbl.renamer(auth_user) %>% tbl_vars
auth_user %>% tbl.renamer %>% tbl_vars
auth_user %>% tbl.renamer(index = c(1,5)) %>% tbl_vars

相关内容

  • 没有找到相关文章

最新更新