7

我喜欢在运行中重命名向量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")))
4

4 回答 4

8

我认为你所说的即时是你希望函数返回修改后的对象。由于rownames<-不会为您执行此操作,因此您必须定义自己的函数:

setRowNames <- function(df, row.names) {
   rownames(df) <- row.names
   df
}

您可以将该函数定义放在脚本的顶部,甚至可以将其隐藏在您的Rprofileor中Rprofile.site(看看?Startup您是否不熟悉)。然后在您的代码中,使用setRowNames(my_df, c("a", "b", "c")). 它简洁、灵活、可读性好。


t(setNames(t(my_df), c("a","b","c")))不起作用,因为转置 data.frame 会为您提供一个没有名称但有行名和列名的矩阵。

于 2013-10-23T14:07:09.597 回答
5

是的,您可以setattrdata.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 函数setnamessetattr修改它们被调用的对象。如果您打算分配给一个新对象,您需要使用以下命令创建一个副本copy

如果您在不知不觉中尝试new_df <- setattr(my_df, "row.names", c("a", "b", "c")) ,那么两者new_dfmy_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"))
于 2013-10-23T15:08:36.867 回答
4
rownames(my_df) <- c("a","b","c")
于 2013-10-23T13:45:17.440 回答
4

我不知道任何“动态”重命名行的内置函数。然而,让 R “即时”执行任何操作的一个方便技巧是使用大括号将多个语句组合成一个语句。例如,如果您有一个数据框df,并且想要将df具有不同行名的副本传递给函数,您可以这样做:

fun({df0<-df;rownames(df0)<-foo;df0})

这有点麻烦,但它仍然比df0在单独的行上定义和重命名,或者编写一个特殊用途的函数来做到这一点更简洁。

这样做的缺点是df0在函数调用之后仍然定义,所以如果你在全局环境中经常这样做,你最终可能会得到很多备用对象。

编辑时:我鼓励任何有兴趣在{}这种情况下使用该成语的人阅读有关此答案的评论。@flodel 和 @RicardoSaporta 是技术娴熟的 R 从业者,他们提出了一些重要观点。{}虽然在这种情况下我碰巧不同意他们的观点,但我建议阅读他们的评论(和我的回复),以了解使用该成语的利弊。

于 2013-10-23T14:16:27.663 回答