R 将结果组织在一个表格中,就像关联矩阵一样
例如,我需要在矩阵中组织我的相关结果。我有这样一个文件:R 将结果组织在一个表格中,就像关联矩阵一样,r,unix,awk,R,Unix,Awk,例如,我需要在矩阵中组织我的相关结果。我有这样一个文件: trait1 trait2 GeCor PCor a b -1.00 0.28 b c 0.40 0.45 d e -0.39 0.35 a c -0.39 0.50 b d 0.36 0.30 a d -0.35 0.30 b e -0
trait1 trait2 GeCor PCor
a b -1.00 0.28
b c 0.40 0.45
d e -0.39 0.35
a c -0.39 0.50
b d 0.36 0.30
a d -0.35 0.30
b e -0.29 0.36
a e 0.26 0.33
c e 0.18 0.38
c d 0.04 0.31
我需要文件保持这样:
a b c d e
a - 0.28 0.50 0.30 0.33
b -1.00 - 0.45 0.30 0.36
c -0.39 0.40 - 0.31 0.38
d -0.35 0.36 0.04 - 0.35
e 0.26 -0.29 0.18 -0.39 -
对角线上的符号(
-
)仅表示此空格应留空。<代码> GECOR 在<代码> TRAIT1和<代码> TRAIT2之间的遗传相关,这些应在空白对角线之下,而#!/usr/bin/python2
import fileinput
finalStruct = {}
diagCh = '-'
delimiter = '\t'
# Build initial structure
for line in fileinput.input():
line = line.rstrip()
columns = line.split(delimiter)
# Create first layer of dictionary inside dictionary
if columns[0] not in finalStruct:
finalStruct[columns[0]] = {}
finalStruct[columns[0]][columns[1]] = columns[3]
if columns[1] not in finalStruct:
finalStruct[columns[1]] = {}
finalStruct[columns[1]][columns[0]] = columns[2]
# Add '-' for diagonals
for currKey in finalStruct.keys():
finalStruct[currKey][currKey] = diagCh
# Output final structure
for rowIndex in sorted(finalStruct.keys()):
for colIndex in sorted(finalStruct[rowIndex].keys()):
print finalStruct[rowIndex][colIndex], delimiter,
print
如果此代码文件为solution.py,而我们的输入文件为:
a b -1.00 0.28
b c 0.40 0.45
d e -0.39 0.35
a c -0.39 0.50
b d 0.36 0.30
a d -0.35 0.30
b e -0.29 0.36
a e 0.26 0.33
c e 0.18 0.38
c d 0.04 0.31
我们的输入文件是input.txt。我们可以按如下方式运行此示例:
cat input.txt | ./solution.py
- 0.28 0.50 0.30 0.33
-1.00 - 0.45 0.30 0.36
-0.39 0.40 - 0.31 0.38
-0.35 0.36 0.04 - 0.35
0.26 -0.29 0.18 -0.39 -
我想是时候用R发布我的解决方案了 首先,使用
read.table
,将原始数据读入数据框,例如x
。然后
n <- ceiling(sqrt(2 * nrow(x)))
NAME <- with(x, sort(union(unique(trait1), unique(trait2))))
z <- matrix(NA_real_, n, n, dimnames = list(NAME, NAME))
z[lower.tri(z)] <- with(x, GeCor[order(trait1, trait2)])
z[upper.tri(z)] <- with(x, PCor[order(trait2, trait1)])
# a b c d e
#a NA 0.28 0.50 0.30 0.33
#b -1.00 NA 0.45 0.30 0.36
#c -0.39 0.40 NA 0.31 0.38
#d -0.35 0.36 0.04 NA 0.35
#e 0.26 -0.29 0.18 -0.39 NA
## write to file "z.txt"
write.table(z, file = "z.txt", na = "-", sep = "\t", quote = FALSE)
a b c d e
a - 0.28 0.5 0.3 0.33
b -1 - 0.45 0.3 0.36
c -0.39 0.4 - 0.31 0.38
d -0.35 0.36 0.04 - 0.35
e 0.26 -0.29 0.18 -0.39 -
nR中的另一种方法,使用包data.table
读取数据和dplyr
:
library(data.table)
df <- fread("trait1 trait2 GeCor PCor
a b -1.00 0.28
b c 0.40 0.45
d e -0.39 0.35
a c -0.39 0.50
b d 0.36 0.30
a d -0.35 0.30
b e -0.29 0.36
a e 0.26 0.33
c e 0.18 0.38
c d 0.04 0.31")
#or df <- fread("myfile.txt")
library(dplyr)
data.frame(trait1=unique(c(df$trait1,df$trait2)), trait2=unique(c(df$trait1,df$trait2)),cor=NA, stringsAsFactors = FALSE) %>%
bind_rows(df %>% mutate(trait1=trait1, trait2=trait2, cor=GeCor, GeCor=NULL, PCor=NULL )) %>%
bind_rows(df %>% mutate(temp=trait2, trait2=trait1, trait1=temp, temp=NULL, cor=PCor, GeCor=NULL, PCor=NULL )) %>%
arrange(trait1, trait2) -> df_long
print.table(matrix(df_long$cor, nrow=5, dimnames=list(unique(df_long$trait1),unique(df_long$trait1))), na.print='-')
a b c d e
a - 0.28 0.50 0.30 0.33
b -1.00 - 0.45 0.30 0.36
c -0.39 0.40 - 0.31 0.38
d -0.35 0.36 0.04 - 0.35
e 0.26 -0.29 0.18 -0.39 -
库(data.table)
df%突变(trait1=trait1,trait2=trait2,cor=GeCor,GeCor=NULL,PCor=NULL))%>%
绑定行(df%>%突变(temp=trait2,trait2=trait1,trait1=temp,temp=NULL,cor=PCor,GeCor=NULL,PCor=NULL))%>%
排列(trait1,trait2)->df_long
print.table(矩阵(df_long$cor,nrow=5,dimnames=list(unique(df_long$trait1),unique(df_long$trait1)),na.print='-'))
a、b、c、d、e
a-0.28 0.50 0.30 0.33
b-1.00-0.45 0.30 0.36
c-0.39 0.40-0.31 0.38
d-0.35 0.36 0.04-0.35
e 0.26-0.29 0.18-0.39-
使用perl
$ perl -ae '
if($. > 1)
{
$h{"$F[0]$F[1]"} = $F[3]; $h{"$F[1]$F[0]"} = $F[2];
push(@hh,$F[0]) if !$done{$F[0]}++;
push(@hh,$F[1]) if !$done{$F[1]}++;
}
END
{
print "\t".join("\t",sort @hh);
foreach (sort keys %h)
{
($k1,$k2) = /./g;
print "\n$k1" if !$seen{$k1}++;
print "\t-" if $k2 eq ++$k1;
print "\t$h{$_}";
}
print "\t-\n";
}' ip.txt
a b c d e
a - 0.28 0.50 0.30 0.33
b -1.00 - 0.45 0.30 0.36
c -0.39 0.40 - 0.31 0.38
d -0.35 0.36 0.04 - 0.35
e 0.26 -0.29 0.18 -0.39 -
- 输入行根据空间分割并保存到
@F
数组中
- 如果输入行大于1,则将第3列和第4列保存在哈希中,并将第1列和第2列的两个组合作为键
- 还可以在数组中保存所有唯一的第1列或第2列值
- 最后,以所需格式打印
带有GNU awk,用于分类输入:
$ cat tst.awk
NR>1 {
cell[$2,$1] = $3
cell[$1,$2] = $4
keys[$1]
keys[$2]
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
printf "%5s", ""
for (col in keys) {
printf " %-5s", col
}
print ""
for (row in keys) {
printf "%s", row
for (col in keys) {
printf " %5s", ((row,col) in cell ? cell[row,col] : "- ")
}
print ""
}
}
$ awk -f tst.awk file
a b c d e
a - 0.28 0.50 0.30 0.33
b -1.00 - 0.45 0.30 0.36
c -0.39 0.40 - 0.31 0.38
d -0.35 0.36 0.04 - 0.35
e 0.26 -0.29 0.18 -0.39 -
与您似乎相信的相反,StackOverflow不是免费的编码服务。您需要显示您的代码,以及相关的示例输入、预期的输出、实际的错误MSG以及您对所处位置的注释。请尽最大努力解决这个问题,人们可能会帮助你。祝你好运。事实上,这只是问题的一小部分,我通过linux编程一个接一个地提取了其他几个文件的结果,由于我对linux的模糊知识,我没有通过这一部分。我尝试了一种超现实的环境。好的,所以我没有解释,但不知为什么我做了很大的努力,但我只是简化了我的问题。是的,你是对的,我不认为在这种情况下,我似乎在努力轻松地赚取这笔钱。谢谢你,下次我会改进我的问题。谢谢你的关注,很抱歉我会重新表述我的问题。我认为你的脚本是在计算行和列索引的名称,而不是从输入文件中读取它们,对吗?为什么不直接使用输入中的任何行/列名?@EdMorton如果特征(1和2)不是从“a”开始的连续字母,那么这确实可能是个问题。它也可以通过使用order(x$trait1)
和order(x$trait2)
代替字母[1:n]
以低成本完成。是的,文件上有名字。我试过了,效果很好。感谢您提供了一种新的方法。wrt没有一个GNU核心实用程序能够轻松地解决这个问题
-不知道为什么这是一个考虑因素,但使用标准UNIX工具awk来解决这个问题绝对是微不足道的,请参阅,而且显然可以用比python FWIW更少的代码行来完成。@EdMorton-我同意awk;不必迂腐,但awk不是一个核心实用程序。我曾考虑过使用awk,但我认为python将更具可读性——可移植到其他系统。最后,我的python代码比您的awk代码短两行(不包括空格、shebang或注释)。然而,我同意awk/perl肯定可以以牺牲可读性的方式用更少的代码行来解决这个问题。我不是说awk是GNU核心实用程序(因为我不知道它是不是),只是没有理由关注工具的子集。我无法想象为什么您会认为python比awk更具可移植性或可读性。您的脚本更简短,因为它不会生成发布的预期输出。显然,我可以通过删除不必要的花括号使awk代码更简洁,也可以通过删除打印行标签和l