根据列名重塑数据框

Reshaping a data frame based on column names

我有一个包含 1 个观察值和 136 个变量的数据框。每个变量都是不同集合的唯一组合,观察值是两组之间的收敛分数。原始 df 的简化版本如下所示:

#Original df
mydf <- data.frame(setA_setB = c(11), setA_setC = c(21), setB_setC = c(31))
mydf

我想要得到的是一个如下所示的数据框:

#Final df
final.mydf <- data.frame(set = c("setA", "setB", "setC"), setA = c(NA, 11, 21), setB = c(11, NA, 31), setC = c(21, 31, NA))
final.mydf

因此,首先需要创建列名和行名,将 mydf 的列名拆分为“_”,我一直在使用以下代码执行此操作:

#List of set names:
setNames <- unique(unlist(strsplit(colnames(mydf), "_")))

然后,我不知道如何根据列名称为矩阵的每个条目分配正确的值。

这里有一个选项tidyverse

library(tidyverse)
data_frame(key = c(names(mydf), sub("(\w+)_(\w+)", "\2_\1", names(mydf))), 
        val = rep(unlist(mydf), 2)) %>%
   separate(key, into = c("set", "key2")) %>%
   spread(key2, val)
# A tibble: 3 × 4
#    set  setA  setB  setC
#* <chr> <dbl> <dbl> <dbl>
#1  setA    NA    11    21
#2  setB    11    NA    31
#3  setC    21    31    NA

我建议使用 reshape 包中的 cast 函数。 我们首先重新定义你的dataframe

redf <- data.frame(cbind(do.call(rbind,(strsplit(names(mydf),"_"))),t(mydf)),stringsAsFactors = F)
names(redf) <- c("set1","set2","value")
redf
#           set1 set2 value
# setA_setB setA setB    11
# setA_setC setA setC    21
# setB_setC setB setC    31

前两列是两组,第三列是对应的值。 因为你想要一个矩阵,意思是“two-ways”。我们切换 set1 和 set2

invdf <- subset(redf,set1!=set2)
names(invdf) <- c("set2","set1","value")
invdf
#           set2 set1 value
# setA_setB setA setB    11
# setA_setC setA setC    21
# setB_setC setB setC    31

最后合并两个dataframe并使用cast

alldf <- rbind(redf,invdf)
alldf$value <- as.numeric(alldf$value)
alldf
library(reshape)
cast(alldf,set1~set2,sum)
#   set1 setA setB setC
# 1 setA    0   11   21
# 2 setB   11    0   31
# 3 setC   21   31    0