我喜欢用setNames
动态重命名一个矢量(我是指一个返回对象的函数):
my_vector <- c(1,2,3)
setNames(my_vector, c("a","b","c"))
# a b c
# 1 2 3
也适用于数据框列名
my_df <- data.frame(matrix(1:9, nrow=3))
setNames(my_df, c("a","b","c"))
a b c
1 1 4 7
2 2 5 8
3 3 6 9
有没有办法对行名称做同样的事情?我认为这会奏效,但事实并非如此:
t(setNames(t(my_df), c("a","b","c")))
答案 0 :(得分:6)
我认为 on-the-fly 的意思是你希望函数返回修改后的对象。由于rownames<-
不适合您,您必须定义自己的功能:
setRowNames <- function(df, row.names) {
rownames(df) <- row.names
df
}
您可以将该功能定义放在脚本的顶部,甚至可以将其隐藏在Rprofile
或Rprofile.site
中(如果您不熟悉,请参阅?Startup
)。然后在代码中使用setRowNames(my_df, c("a", "b", "c"))
。它简洁,灵活,读起来很好。
t(setNames(t(my_df), c("a","b","c")))
不起作用,因为转置data.frame会为您提供一个矩阵,该矩阵没有名称,只有rownames和colnames。
答案 1 :(得分:6)
是的,您可以使用setattr
包
data.table
library(data.table)
(setattr(my_df, "row.names", c("a", "b", "c")))
X1 X2 X3
a 1 4 7
b 2 5 8
c 3 6 9
实际上,对象被修改到位(这对大对象非常有用 - 不复制对象)。几乎任何属性都可以使用它。
请注意setattr
无形地返回对象。
与setNames
不同,data.table函数setnames
和setattr
修改了它们被调用的对象。如果您计划分配给新对象,则需要使用copy
:
如果您在不知不觉中尝试new_df <- setattr(my_df, "row.names", c("a", "b", "c"))
然后new_df
和my_df
都会有相同的值
在这种情况下,您需要使用copy(my_df)
:
new_df <- setattr(copy(my_df), "row.names", c("a", "b", "c"))
但是,如果您的目标是“重新分配”回my_df
,那么您可以节省一些按键:
## instead of
my_df <- setattr(my_df, "row.names", c("a", "b", "c"))
## you can simply execute
setattr(my_df, "row.names", c("a", "b", "c"))
答案 2 :(得分:4)
我不知道任何“动态”重命名行的内置函数。然而,让R在“动态”做任何事情的一个方便的技巧是使用大括号将多个语句组合成一个语句。例如,如果您有一个数据框df
并且想要将具有不同行名的df
副本传递给函数,则可以执行以下操作:
fun({df0<-df;rownames(df0)<-foo;df0})
这有点麻烦,但它比在单独的行上定义和重命名df0
或编写专用函数更加简洁。
这样做的缺点是在函数调用之后仍然定义df0
,所以如果你在全局环境中做了很多这样的事情,你可能会得到很多备用对象。
编辑:我会鼓励任何有兴趣使用{}
成语的人阅读此答案的评论。 @flodel和@RicardoSaporta是高技能的R从业者,他们提出了一些重点。虽然在这种情况下我碰巧不同意他们,但我建议阅读他们的评论(和我的回复),以了解使用{}
成语的利弊。
答案 3 :(得分:1)
rownames(my_df) <- c("a","b","c")