<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>生信菜鸟团 &#187; 多公共列合并</title>
	<atom:link href="http://www.bio-info-trainee.com/tag/%e5%a4%9a%e5%85%ac%e5%85%b1%e5%88%97%e5%90%88%e5%b9%b6/feed" rel="self" type="application/rss+xml" />
	<link>http://www.bio-info-trainee.com</link>
	<description>欢迎去论坛biotrainee.com留言参与讨论，或者关注同名微信公众号biotrainee</description>
	<lastBuildDate>Sat, 28 Jun 2025 14:30:13 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.33</generator>
	<item>
		<title>用R和mysql把基因对应的最大表达量探针挑出来</title>
		<link>http://www.bio-info-trainee.com/1069.html</link>
		<comments>http://www.bio-info-trainee.com/1069.html#comments</comments>
		<pubDate>Thu, 22 Oct 2015 02:15:21 +0000</pubDate>
		<dc:creator><![CDATA[ulwvfje]]></dc:creator>
				<category><![CDATA[R]]></category>
		<category><![CDATA[分组求最大值]]></category>
		<category><![CDATA[多公共列合并]]></category>

		<guid isPermaLink="false">http://www.bio-info-trainee.com/?p=1069</guid>
		<description><![CDATA[懂点芯片数据分析的都应该知道，芯片设计的时候，对一个基因设计了多个探针，这样设计 &#8230; <a href="http://www.bio-info-trainee.com/1069.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>懂点芯片数据分析的都应该知道，芯片设计的时候，对一个基因设计了多个探针，这样设计是为了更好的捕获某些难以发现的基因，或者重点研究某些基因。<br />
但是对我们的差异分析不方便，所以我们只分析哪些有对应了entrez ID的探针，而且对每个entrez ID，我们只需要挑选它表达量最高的那个探针。<br />
所以就演化为一个编程问题：分组求最大值，多公共列合并！<br />
如果是在R语言里面，那么首先这个table的表示形式如下<br />
&gt; esetDataTable[1:10,c(7,8)]<br />
EGID rowMeans<br />
1000_at 5595 1840.04259751826<br />
1001_at 7075 799.075414422572<br />
1002_f_at 1557 50.4884096416177<br />
1003_s_at 643 142.372008051308<br />
1004_at 643 211.65300963049<br />
1005_at 1843 4281.29318032004<br />
1006_at 4319 38.5784289213085<br />
1007_s_at NA 1489.98158531843<br />
1008_f_at 5610 4013.576753977<br />
1009_at 3094 3070.50648167305<br />
我们首先看看一个R语言函数处理方式吧，这个是比较容易想到的算法，但是用到了循环，非常的不经济，计算量很大。</p>
<p><a href="http://www.bio-info-trainee.com/wp-content/uploads/2015/10/Capture11.png"><img class="alignnone size-full wp-image-1075" src="http://www.bio-info-trainee.com/wp-content/uploads/2015/10/Capture11.png" alt="Capture1" width="631" height="344" /></a><br />
因为里面涉及到了双重循环。我进行了人工计时，这个程序耗费了一分钟十二秒，程序里面的计时器有点问题。</p>
<p>然后我再讲一个精简版的算法<br />
dat=esetDataTable[,c(7,8)]<br />
dat=as.data.frame(apply(dat,2,as.numeric))<br />
dat$prob=rownames(esetDataTable)<br />
首先可以得到需要提取的数据所在行的两个值<br />
match_row=aggregate(dat,by=list(dat[,1]),max)<br />
类似于这句SQL语句：SELECT max(a.rowMeans) as val, a.EGID FROM test.esetDataTable a group by a.EGID<br />
现在要根据match_row表去原表esetDataTable里面提取我们的探针ID数据。</p>
<p><img class="alignnone size-full wp-image-1076" src="http://www.bio-info-trainee.com/wp-content/uploads/2015/10/Capture21.png" alt="Capture2" width="453" height="460" /></p>
<p>这样就完美解决了问题，我们的合并后的数据的prob列，就是前面那个函数计算了一分多钟的返回的非冗余探针ID向量，relevantProbesets，但是这次只花了不到一秒钟。<br />
tmp_prob=merge(dat,match_row,by=c("EGID","rowMeans"))<br />
setdiff(as.character(relevantProbesets),as.character(tmp_prob$prob))<br />
length(union(as.character(relevantProbesets),as.character(tmp_prob$prob)))<br />
setdiff(as.character(tmp_prob$prob),as.character(relevantProbesets))<br />
我顺便检查了一下上面那个复杂的R函数跟我这次精简版的结果，发现这次才是对的，上面那个错了。<br />
你们能发现上面那个为什么错了吗？</p>
<p>如果是在mysql里面它的表现形式如下；<br />
mysql&gt; select row_names,EGID,rowMeans from esetDataTable order by EGID limit 10;<br />
+------------+-------+------------------+<br />
| row_names | EGID | rowMeans |<br />
+------------+-------+------------------+<br />
| 38912_at | 10 | 85.8820246154773 |<br />
| 41654_at | 100 | 301.720067595558 |<br />
| 907_at | 100 | 273.100008206028 |<br />
| 2053_at | 1000 | 354.207060199715 |<br />
| 2054_g_at | 1000 | 33.8472900312781 |<br />
| 40781_at | 10000 | 425.007640082848 |<br />
| 35430_at | 10001 | 152.885791914329 |<br />
| 35431_g_at | 10001 | 181.915087187117 |<br />
| 35432_at | 10001 | 184.869017764782 |<br />
| 31366_at | 10002 | 44.9716205901791 |<br />
+------------+-------+------------------+<br />
10 rows in set (0.05 sec)</p>
<p>如果要用SQL来做同样的事情需要下面这个语句，这个就非常简单啦！<br />
select b.*<br />
from test.esetDataTable b<br />
inner join (<br />
SELECT max(a.rowMeans) as val, a.EGID FROM test.esetDataTable a group by a.EGID<br />
) as c on b.EGID=c.EGID and b.rowMeans=c.val<br />
结果是：8640 rows in set (4.56 sec) 看起来mysql还没有R语言快速，但是这个mysql语句很明显也不是很高效，但是我的mysql水平有限。<br />
稍微解释一下这个mysql语句，其中SELECT max(a.rowMeans) as val, a.EGID FROM test.esetDataTable a group by a.EGID类似于R里面的match_row=aggregate(dat,by=list(dat[,1]),max)，就是把每个entrez ID对应着的最大值提取出来成一个新的表<br />
而inner join on b.EGID=c.EGID and b.rowMeans=c.val 就是我们的tmp_prob=merge(dat,match_row,by=c("EGID","rowMeans")) 根据两列来合并两个数据框</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bio-info-trainee.com/1069.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
