如何在执行函数时一步更改列名?

时间:2015-07-30 03:01:26

标签: r

我有一个名为newBamAD的函数,当我将此函数运行到输入数据框output时,会给出以下mydf(见下文)。我想通过将列名bam.AD更改为新列名来存储newBamAD(mydf)的结果。例如,当我使用我的数据框bam.AD运行函数时,我想在同一步骤中将列名output<-newBamAD(mydf)更改为新名称。

  output
       start           REF ALT bam.AD  
    1  "chr20:5363934" "C" "T" "59,29" 
    2  "chr5:8529759"  "G" "C" "28,41" 
    3  "chr14:9620689" "T" "G" "49,41" 

我想要这样

output


               start           REF ALT newname.AD  
            1  "chr20:5363934" "C" "T" "59,29" 
            2  "chr5:8529759"  "G" "C" "28,41" 
            3  "chr14:9620689" "T" "G" "49,41" 

1 个答案:

答案 0 :(得分:2)

重要的是你有矩阵还是data.frame。矩阵使用dimnames属性存储行名和列名,而data.frames使用namesrow.names属性分别存储列名和行名。

从您的问题来看,您似乎在output中有一个矩阵,因为data.frames通常不会引用字符元素(无论它们是否是实际因素或真实的字符向量)打印时,矩阵。

因此,要更改列名,必须使用colnames<-()函数。 (您也可以使用dimnames<-()函数,但这需要一个包含两个组件的列表RHS,一个用于行名称,另一个用于列名称,并且由于您不想弄乱行名称,因此#39;没用。)

如果你想在与函数调用相同的行中执行此操作,则必须使用反引号调用colnames<-()来保护解析器中的<-令牌。因此我们有:

mydf <- data.frame(); ## dummy
newBamAD <- function(mydf) matrix(c('chr20:5363934','chr5:8529759','chr14:9620689','C','G','T','T','C','G','59,29','28,41','49,41'),3,dimnames=list(1:3,c('start','REF','ALT','bam.AD')));
newBamAD(mydf);
##   start           REF ALT bam.AD
## 1 "chr20:5363934" "C" "T" "59,29"
## 2 "chr5:8529759"  "G" "C" "28,41"
## 3 "chr14:9620689" "T" "G" "49,41"
`colnames<-`(newBamAD(mydf),c('start','REF','ALT','newname.AD'));
##   start           REF ALT newname.AD
## 1 "chr20:5363934" "C" "T" "59,29"
## 2 "chr5:8529759"  "G" "C" "28,41"
## 3 "chr14:9620689" "T" "G" "49,41"

这有一个明显的缺点,你必须为所有列指定名称,而不仅仅是你想要替换的那些列,但我不知道如何解决这个问题,如果你想要内联这样做。您当然可以先将感兴趣的列编入索引,但之后您将丢失剩余的列,这样就无法工作。

当然没有什么可以阻止你捕获变量中的返回值,然后通过索引赋值在一个单独的语句中有选择地替换列名,这可以使用分号在同一行上完成:< / p>

output <- newBamAD(mydf); colnames(output)[colnames(output)=='bam.AD'] <- 'newname.AD';
output;
##   start           REF ALT newname.AD
## 1 "chr20:5363934" "C" "T" "59,29"
## 2 "chr5:8529759"  "G" "C" "28,41"
## 3 "chr14:9620689" "T" "G" "49,41"

或者,您可以将结果作为data.frame而不是矩阵返回,或者通过as.data.frame()强制返回data.frame,在这种情况下,您可以使用setNames()names<-() ,与上述colnames<-()解决方案有相同的考虑。

如果您愿意采用data.frame路线,则会出现另一种可能性。这是使用transform()(或within(),但transform()对于我们的目的来说更简洁。实际上,通过测试,您可以直接在矩阵上应用此函数,它会自动强制转换为data.frame,这很方便。因此我们有:

transform(newBamAD(mydf),newname.AD=bam.AD,bam.AD=NULL);
##           start REF ALT newname.AD
## 1 chr20:5363934   C   T      59,29
## 2  chr5:8529759   G   C      28,41
## 3 chr14:9620689   T   G      49,41

这种方法的缺点是必须复制列数据,而使用以前的解决方案只需要触及命名属性。

我建议使用双语句解决方案。