4

这是参考这个问题

我想重命名大型数据框中的列子集。我希望以下代码将列、、 X4X5分别重命名为、、、X6和:X7gradekgrade1grade2grade3

set.seed(1)
in.df <- data.frame( matrix( rnorm(60), ncol=10) )
names(in.df) <- ifelse( names(in.df) %in% c('X4', 'X5', 'X6', 'X7'),
                         paste('grade', c('k',1:3), sep=''),
                         names(in.df) )

然而,

> names(in.df)
 [1] "X1"     "X2"     "X3"     "grade3" "gradek" "grade1" "grade2" "X8"    
 [9] "X9"     "X10"   

虽然

> paste('grade', c('k',1:3), sep='')
[1] "gradek" "grade1" "grade2" "grade3"

表明订单没有被保留。这个线程,建议使用match而不是%in%会工作,但在这种情况下它不会。(也许在其他版本的 R 中也是如此。在我安装的版本(2.15.3)中,帮助页面上的match建议%in%是通过这样定义的,match因此切换它没有帮助。)

任何帮助,将不胜感激!

接受的答案 这个答案解决了我的重命名问题。 这个答案解释了奇怪的行为是由于回收。

4

2 回答 2

5

%in%应该工作,但也许match更好。

考虑以下。“A”和“B”代表您的names(in.df). 我们希望使用 的结果以该顺序替换“matchme”中paste('grade', c('k',1:3), sep='')的值。

比较不同的输出:

A <- B <- c("X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10")
matchme <- c('X4', 'X7', 'X6', 'X5')
A[A %in% matchme] <- paste('grade', c('k',1:3), sep='')
A
#  [1] "X1"     "X2"     "X3"     "gradek" "grade1" "grade2" "grade3" "X8"    
#  [9] "X9"     "X10"  
B[match(matchme, B)] <- paste('grade', c('k',1:3), sep='')
B
#  [1] "X1"     "X2"     "X3"     "gradek" "grade3" "grade2" "grade1" "X8"    
#  [9] "X9"     "X10"   
于 2013-04-19T18:24:18.460 回答
4

Ananda 的回答给出了如何做你想做的事的好方法。相反,我将回答这个问题,即为什么你得到了你所做的结果而不是你预期的结果。

名称看起来乱序的原因与ifelse工作原理和参数回收有关。让我们看一下 的三个参数ifelse

> list(names(in.df) %in% c('X4', 'X5', 'X6', 'X7'),
+      paste('grade', c('k',1:3), sep=''),
+      names(in.df))
[[1]]
 [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE

[[2]]
[1] "gradek" "grade1" "grade2" "grade3"

[[3]]
 [1] "X1"  "X2"  "X3"  "X4"  "X5"  "X6"  "X7"  "X8"  "X9"  "X10"

ifelse根据第一个参数是 TRUE 还是 FALSE 来决定选择哪个对应元素。但是第二个参数没有第一个长,所以它被回收为正确的长度。将它们放入 data.frame 以便并排查看它们更容易,并手动扩展第二组名称,给出:

> data.frame(test = names(in.df) %in% c('X4', 'X5', 'X6', 'X7'),
+            `TRUE` = rep(paste('grade', c('k',1:3), sep=''),length=10),
+            `FALSE` = names(in.df))
    test  TRUE. FALSE.
1  FALSE gradek     X1
2  FALSE grade1     X2
3  FALSE grade2     X3
4   TRUE grade3     X4
5   TRUE gradek     X5
6   TRUE grade1     X6
7   TRUE grade2     X7
8  FALSE grade3     X8
9  FALSE gradek     X9
10 FALSE grade1    X10

因此使用了新名称的第 4、5、6 和 7 个元素,由于参数循环,它们对应于第 4、1、2 和 3 个。

于 2013-04-19T18:32:17.920 回答