在管道 R 工作流中为大多数 data.frame 变量名称添加前缀或后缀
Adding prefix or suffix to most data.frame variable names in piped R workflow
我想为 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")
据我所知不存在。
这有点快,但不完全是你想要的:
dat14 %>%
group_by(class) %>%
select(-ID) %>%
summarise_each(funs(mean(.))) -> means14
names(means14)[-1] %<>% paste0("_mean_2014")
如果您之前没有使用过 %<>% 运算符,一定要检查这个 link,它是一个超级有用的工具。
你也可以用它来重新计算或舍入一些列,像这样 df$meancolumn %<>% round()
等等,它经常出现并且可以节省你很多写作
在发布这个问题后进行了额外的试验后,我发现 setNames
函数可以与管道一起使用,因为它 returns a 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
这更像是倒退一步,但您可能会考虑重塑数据,以便同时将该函数应用于多年。这将保持整洁。如果您最终想要比较不同的年份,那么将年份作为数据框中的单独变量可能是有意义的,而不是将年份存储在名称中。您应该能够使用 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()
的 Sam Firkes 解决方案肯定是保持管道不间断的唯一解决方案,但它不适用于 dplyr
中的 tbl
对象,因为列名不是可以通过通常的基本 R 命名函数的方法访问。由于 hrbrmstr 的 解决方案,您也可以在带有 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
对象):
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
自 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!
您可以将函数传递给 rename_at,
也可以
means14 <- dat14 %>%
group_by(class) %>%
select(-ID) %>%
summarise_all(funs(mean(.))) %>%
rename_at(vars(-class),function(x) paste0(x,"_2014"))
我想为 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")
据我所知不存在。
这有点快,但不完全是你想要的:
dat14 %>%
group_by(class) %>%
select(-ID) %>%
summarise_each(funs(mean(.))) -> means14
names(means14)[-1] %<>% paste0("_mean_2014")
如果您之前没有使用过 %<>% 运算符,一定要检查这个 link,它是一个超级有用的工具。
你也可以用它来重新计算或舍入一些列,像这样 df$meancolumn %<>% round()
等等,它经常出现并且可以节省你很多写作
在发布这个问题后进行了额外的试验后,我发现 setNames
函数可以与管道一起使用,因为它 returns a 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
这更像是倒退一步,但您可能会考虑重塑数据,以便同时将该函数应用于多年。这将保持整洁。如果您最终想要比较不同的年份,那么将年份作为数据框中的单独变量可能是有意义的,而不是将年份存储在名称中。您应该能够使用 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()
的 Sam Firkes 解决方案肯定是保持管道不间断的唯一解决方案,但它不适用于 dplyr
中的 tbl
对象,因为列名不是可以通过通常的基本 R 命名函数的方法访问。由于 hrbrmstr 的 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
对象):
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
自 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!
您可以将函数传递给 rename_at,
也可以 means14 <- dat14 %>%
group_by(class) %>%
select(-ID) %>%
summarise_all(funs(mean(.))) %>%
rename_at(vars(-class),function(x) paste0(x,"_2014"))