R从其他列表/数据框创建新列表

时间:2015-08-15 10:40:23

标签: r for-loop

我计划简化这个问题,但为了清晰起见,我决定发布原始代码。我正在尝试创建一个包含1874个列表元素的列表score_loc,并从三个不同的数据集中提取数据:loc_preloc_locatecsv_t。为了创建这个列表,我无法使用for循环为每个列表元素分配数据帧,这非常慢,因为数据非常大,并且给我带来错误。

可重复数据

Shortened csv_t.csv包含前20000行

csv_t.csv dropbox link

loc_pre.csv dropbox link

对于loc_locate,有点难以显示数据帧列表的可重现示例。

以前确定的一些数据:

head(loc_pre)  # 1874 rows 
#   start   end
# 1  4844  4852
# 2  5954  5962
# 3  7896  7904
# 4 12301 12309
# 5 18553 18561
# 6 18670 18678

loc_locate  # a list of varying lengths of dataframes; 1874 list elements
# [[1]]
#      start end
# [1,]     6   6
#
# [[2]]
#      start end
# [1,]     1   1
# [2,]     6   6
# [3,]     9   9
#
# [[3]]
#      start end
# [1,]     6   6
# [2,]     8   8

head(csv_t)  # 4524203 rows, tpl column values are consecutively increasing by 1
#     tpl score 
# 1: 3239     6 
# 2: 3240     6 
# 3: 3241     7 
# 4: 3242    13 
# 5: 3243     0 
# 6: 3244     6 

期望的输出:

您可以看到loc_pre的行号与loc_locate的列表元素编号相对应。 loc_locate表示loc_pre中相应起始位置的位置编号。例如,如果你取loc_locate的第一个元素和loc_pre的第一行,你可以告诉你在4844,4845,4846,4847,4488,4849,4850,4851寻找第6个位置在这种情况下,这个理想的位置是4849.

遵循这一逻辑,我想创建一个包含1874个列表元素的新列表score_loc,它会显示每个单独行loc_pre的所需位置的开始,结束和得分。分数列来自csv_t。

score_loc
# [[1]]
#      start end score
# [1,]     6   6    10   # score corresponding to position (4844 + 6 - 1)
#
# [[2]]
#      start end score
# [1,]     1   1     1   # score corresponding to position (5954 + 1 - 1)
# [2,]     6   6     2   # score corresponding to position (5954 + 6 - 1)
# [3,]     9   9     8   # score corresponding to position (5954 + 9 - 1)
#
# [[3]]
#      start end score
# [1,]     6   6    19   # score corresponding to position (7896 + 6 - 1)
# [2,]     8   8    11   # score corresponding to position (7896 + 8 - 1)

我的代码

正如我之前提到的,我正在使用for循环来尝试实现这一点,但这种方法花费的时间太长了。我希望你能通过查看我的代码更清楚地了解我想要实现的目标。

score_loc <- list()
for(w in 1:nrow(loc_pre)){
   vectornom <- loc_pre[w, 1] + loc_locate[[w]][,"start"] - 1
   score_loc[[w]] <- data.frame(csv_t[csv_t$tpl %in% vectornom,][, 4, with=F]) # takes a long time for some reason
}

1 个答案:

答案 0 :(得分:1)

一种方法是使用mapply功能:

# Expand the sequences
preList <- apply(loc_pre, 1, function(X) X[1]:X[2])

# Function to build tpl datasets
posFun <- function(Seq, Loc) {
  cbind(Loc, tpl = apply(Loc, 1, function(X, S) S[X[1]:X[2]], S = Seq))
}

# Apply, combine and merge    
mOutput <- mapply(posFun, preList, loc_locate)
mIndex <- rep(1:length(mOutput), sapply(mOutput, nrow)) # Not sure if you need this, but have included for now
combineData <- data.frame(Index = mIndex, do.call("rbind", mOutput))
merge(combineData, csv_t, all.x = TRUE)

查看数据样本,我们似乎可以将其简化为:

posFun <- function(Seq, Loc) cbind(Loc, tpl = Seq + Loc[,1] - 1)
mOutput <- mapply(posFun, loc_pre$start, loc_locate)
merge(do.call("rbind", mOutput), csv_t, all.x = TRUE)
#    tpl start end score
# 1 4849     6   6     6
# 2 5954     1   1     4
# 3 5959     6   6     7
# 4 5962     9   9     6
# 5 7901     6   6     2
# 6 7903     8   8     1

注意:我已经在此示例中随机生成了我的分数