我在R.工作。我有一个数据框,其中包含染色体上的起始位置和结束位置(整数表示染色体上的坐标)例如:
start end
1 5
3 7
4 10
12 7 (inverted is also allowed)
8 15
我想要的是计算所有这些范围内坐标的出现次数。因此,对于上面的示例,输出将是:
position count
1 1
2 1
3 2
4 3
5 3
6 2
7 3
8 3
9 3
10 3
11 2
12 2
13 1
14 1
15 1
我有62000多个这样的范围,每个范围至少有1000个位置。我知道如何进行这种转换,但我不知道如何有效地完成这项工作,即几秒钟。
当前(效率低下的代码)
positions <- c()
for(i in seq(nrow(a))){
positions <- c(positions, seq(a[i,3], a[i,4]))
}
table(positions)
“a”是我的数据框,起点和终点坐标分别在第三和第四列。
数据框中的一列包含字符,因此对于使用apply
,我要么需要创建一个新的数据框(消耗额外的空间),要么需要在apply函数内转换为整数(额外的时间)。对不起,因为之前没有告知此事。
答案 0 :(得分:9)
对于<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button"> button</div>
<div class="button"> button</div>
<div class="button"> button</div>
<div class="button_place">button_place</div>
<div class="button_place">button_place</div>
<div class="button_place">button_place</div>
的非常快的代码,请参阅 docendo discimus 的答案
(+基准)
以下是其他一些解决方案的基准:
@TabFactory("pages.properties.label")
public void pageProperties(UiConfig cfg, TabBuilder tab) {
List<String> targetGroup = new ArrayList<>();
targetGroup.add(new OptionBuilder().value("Group A").label("Group A").selected());
targetGroup.add(new OptionBuilder().value("Group B").label("Group B").selected());
List<String> menuTeaser = new ArrayList<>();
menuTeaser.add(new OptionBuilder().value("Group A").label("Teaser A").selected());
menuTeaser.add(new OptionBuilder().value("Group A").label("Teaser B").selected());
tab.fields(
cfg.fields.text("pageTitle").label("pages.properties.pageTitle.label").i18n()
.description("pages.properties.pageTitle.description").i18n()
.defaultValue("any value").i18n() // works!
.requiredErrorMessage("pages.properties.pageTitle.requiredErrorMessage").i18n()
.required(),
cfg.fields.select("targetGroup").label("pages.properties.targetGroup.label").i18n()
.description("pages.properties.targetGroup.description").i18n()
.options(targetGroup.toArray(new OptionBuilder[targetGroup.size()])).i18n(),
cfg.fields.optionGroup("menuTeaser").label("pages.properties.menuTeaser.label").i18n()
.description("pages.properties.menuTeaser.description").i18n()
.options(menuTeaser.toArray(new OptionBuilder[menuTeaser.size()])).i18n()
.required(),
);
}
data.table
的解决方案会产生警告。
答案 1 :(得分:7)
一个想法,
http://www.dn.pt/pesquisa.html?q=economia%20empresas
答案 2 :(得分:4)
这与您使用的算法大致相同,但应该更快。
myNums <- unlist(lapply(seq_len(nrow(df)), function(i) seq(df$start[i], df$end[i])))
table(myNums)
myNums
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1 2 3 3 2 3 3 3 3 2 2 1 1 1
更快的方法是使用tabulate
而不是table
。例如,
temp <- unlist(lapply(seq_len(nrow(df)), function(i) seq(df$start[i], df$end[i])))
cbind(sort(unique(temp)), tabulate(temp))
返回矩阵
[,1] [,2]
[1,] 1 1
[2,] 2 1
[3,] 3 2
[4,] 4 3
[5,] 5 3
[6,] 6 2
[7,] 7 3
[8,] 8 3
[9,] 9 3
[10,] 10 3
[11,] 11 2
[12,] 12 2
[13,] 13 1
[14,] 14 1
[15,] 15 1
对于给定的数据集,运行速度提高约50%。
Unit: microseconds
expr min lq mean median uq max neval cld
table 223.233 237.6305 250.0329 245.8985 253.4545 423.944 100 b
tabulate 142.835 159.0860 166.9775 167.3540 175.7650 195.009 100 a
答案 3 :(得分:4)
我会提出一个data.table解决方案,因为我们对性能感兴趣。方法如下:
library(data.table)
setDT(df)
df[, list(seq.int(start, end)), by = 1:nrow(df)][, .N, by = V1]
尽管采用行式操作,但与其他解决方案相比,它的表现非常好。
以下是 1e4 行的基准:
set.seed(42)
N <- 1e4
vals = 1:100
df <- data.frame(start=sample(vals, N, replace = TRUE), end = sample(vals, N, replace = TRUE))
library(data.table)
library("microbenchmark")
dt <- copy(df)
setDT(dt)
microbenchmark(unit = "relative", times = 10,
jogo = table(unlist(Map(seq, df$start, df$end))), # jogo
sotos = table(unlist(Map(':', df$start, df$end))), # Sotos
lmo = table(unlist(lapply(seq_len(nrow(df)), function(i) seq(df$start[i], df$end[i])))), # lmo
orig_989 = table(do.call(c, mapply(seq, df$start, df$end))), # @989 (comment to the answer from Sotos)
mod_989 = table(do.call(c, mapply(seq.int, df$start, df$end))), # docendo discimus (comment to this answer)
dd = dt[, list(seq.int(start, end)), by = 1:nrow(dt)][, .N, by = V1]
)
Unit: relative
expr min lq mean median uq max neval cld
jogo 8.794179 8.735461 19.226146 8.584978 8.637774 52.782168 10 ab
sotos 10.669810 10.623685 8.984351 10.437937 10.164045 4.846189 10 ab
lmo 21.319154 21.117393 27.452902 22.558436 22.913901 43.403024 10 b
orig_989 9.190209 8.725191 7.532509 8.730023 8.516305 3.948500 10 ab
mod_989 5.372087 5.097636 5.067462 5.305532 6.214493 3.188091 10 ab
dd 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 10 a
答案 4 :(得分:2)
我为fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param HTTP_PROXY "";
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
fastcgi_param OAUTH_TOKEN $http_oauth_token;
fastcgi_param OAUTH_TOKEN_SECRET $http_oauth_token_secret;
中的每一行创建了一个序列,例如第一行df
。使用:
c(1,2,3,4,5)
表格将计算all.pos <- apply(df, 1, function(x){x[1]:x[2]})
all.pos <- unlist(all.pos)
# 1 2 3 4 5 3 4 5 6 7 4 5 6 7 8 9 10 12 11 10 9 8 7 8 9
# 10 11 12 13 14 15
中每个职位的出现频率。
all.pos
答案 5 :(得分:2)
另一种避免table
的方法,循环遍历范围并每次向相关值添加1 ......
ranges <- data.frame(start=c(1,3,4,12,8), end=c(5,7,10,7,15) )
pos <- data.frame(x=(min(ranges):max(ranges)),n=0)
for(i in seq_along(ranges$start)){
low=min(ranges$start[i])-pos$x[1]+1
high=max(ranges$end[i])-pos$x[1]+1
pos$n[low:high] <- pos$n[low:high]+1
}
pos
x n
1 1 1
2 2 1
3 3 2
4 4 3
5 5 3
6 6 2
7 7 3
8 8 3
9 9 3
10 10 3
11 11 2
12 12 2
13 13 1
14 14 1
15 15 1
答案 6 :(得分:1)
首先出现的可能不是最好的,但通过使用应用的东西应该会更快。
df <- data.frame(start=c(1,3,4,12,8), end=c(5,7,10,7,15) )
positions <- apply(df, 1, function (x) {
seq(x[1], x[2])
})
table(unlist(positions))
产量..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1 2 3 3 2 3 3 3 3 2 2 1 1 1