如何通过交替列名复制数据框中的列

时间:2017-08-07 01:07:37

标签: r dplyr

我有以下数据框:


df <- structure(list(Vertebral = c(16.43, 1.06, 0.38), BoneMarrow = c(19.69, 
1.16, 1.13)), .Names = c("Vertebral", "BoneMarrow"), row.names = c("Gnai3", 
"Cdc45", "Cav2"), class = "data.frame")

df
#>       Vertebral BoneMarrow
#> Gnai3     16.43      19.69
#> Cdc45      1.06       1.16
#> Cav2       0.38       1.13

我想要做的是创建如下所示的数据框:

即为每个原始列名称创建两个副本:使用&#39; control&#39;并且&#39;对待&#39;作为后缀。

      Vertebral.control  BoneMarrow.control Vertebral.Treated BoneMarrow.Treated
Gnai3     16.43          19.69             16.43               19.69
Cdc45      1.06          1.16              1.06                1.16
Cav2       0.38          1.13              0.38                1.13

我该怎么做?

我坚持使用这段代码:


library(tidyverse)

subtype <- colnames(df)
expand.grid(subtype,c("Control","Treated")) %>% 
 mutate(new_col =  paste0( Var1,".",Var2 ))
#>         Var1    Var2            new_col
#> 1  Vertebral Control  Vertebral.Control
#> 2 BoneMarrow Control BoneMarrow.Control
#> 3  Vertebral Treated  Vertebral.Treated
#> 4 BoneMarrow Treated BoneMarrow.Treated

3 个答案:

答案 0 :(得分:2)

您可以尝试cbind

x1 <- setNames(df, paste0(names(df), '.', 'control'))
x2 <- setNames(df, paste0(names(df), '.', 'Treated'))
cbind(x1, x2)

#       Vertebral.control BoneMarrow.control Vertebral.Treated BoneMarrow.Treated
# Gnai3             16.43              19.69             16.43              19.69
# Cdc45              1.06               1.16              1.06               1.16
# Cav2               0.38               1.13              0.38               1.13

使用rlang::symdplyr的替代解决方案:

x <- syms(rep(names(df), 2))
names(x) <- paste0(rep(names(df), 2), rep(c('.control', '.Treated'), each = ncol(df)))
res <- df %>% mutate(!!!x)
rownames(res) <- rownames(df)

!!!会获取一系列元素并将它们拼接到一起调用(考虑do.call的作用),可以在here找到更多信息。

答案 1 :(得分:2)

应该可以轻松扩展到更多列和组的版本:

newdf <- df[0] # creates an empty data.frame with the same row count
newdf[paste(names(df), rep(c("control","treated"),each=ncol(df)), sep=".")] <- df
newdf

#      Vertebral.control BoneMarrow.control Vertebral.treated BoneMarrow.treated
#Gnai3             16.43              19.69             16.43              19.69
#Cdc45              1.06               1.16              1.06               1.16
#Cav2               0.38               1.13              0.38               1.13

答案 2 :(得分:1)

我会采用cbind

这样的简单方法
df2 = cbind(df, Vertebral.Treated=rep(df$Vertebral), BoneMarrow.Treated =rep(df$BoneMarrow)) 

print(df2)
     Vertebral BoneMarrow Vertebral.Treated BoneMarrow.Treated
Gnai3     16.43      19.69             16.43              19.69
Cdc45      1.06       1.16              1.06               1.16
Cav2       0.38       1.13              0.38               1.13

您可以创建所需的任意数量的列。另请参阅此link