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

时间:2015-04-29 15:58:11

标签: r dplyr magrittr

我想为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")

据我所知,这是不存在的。

6 个答案:

答案 0 :(得分:15)

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

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

答案 1 :(得分:4)

这有点快,但不完全是你想要的:

dat14 %>%
  group_by(class) %>%
  select(-ID) %>%
  summarise_each(funs(mean(.))) -> means14 

names(means14)[-1] %<>% paste0("_mean_2014")

如果您没有使用%&lt;&gt;% - 运算符,请务必先检查此link,这是一个非常有用的工具。

你也可以用它来重新计算或舍入一些列,比如df$meancolumn %<>% round(),等等,它只是经常出现,只是为你节省了大量的文字

答案 2 :(得分:4)

自发布此问题后进行了额外的实验后,我发现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

答案 3 :(得分:4)

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

在这个例子中你可以这样做。

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

这与使用set_names的答案非常相似,但也适用于反复尝试!

答案 4 :(得分:0)

这更像是退一步,但您可能会考虑重塑数据,以便同时将该功能应用于多年。这样可以保持整洁。如果您希望最终比较不同的年份,那么将年份作为数据框中的单独变量可能是有意义的,而不是将年份存储在名称中。您应该能够使用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))`

答案 5 :(得分:0)

虽然使用setNames()的Sam Firkes解决方案当然是保留完整管道的唯一解决方案,但它不适用于来自tbl的{​​{1}}个对象,因为列名无法通过来自通常的基本R命名函数的方法。这是一个可以在具有dplyr个对象的管道中使用的函数,这要归功于hrbrmstr的this解决方案。它在指定的列索引处添加预定义的前缀和后缀。默认是所有列。

tbl

示例用法(假设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对象:

tbl_sql