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

问题描述:

我计划简化这个问题,但我决定只发布我的原始代码以便清晰。我试图创建一个列表score_loc,其中包含1874个列表元素,并从三组不同的数据中提取数据:loc_pre,loc_locatecsv_t。为了创建这个列表,我没有有效地使用for循环来为每个列表元素分配数据帧,这是非常缓慢的,因为数据非常大,给我错误。R从其他列表/数据框中创建新列表

重复性的数据

Shortened csv_t.csv包含第一20000行

csv_t.csv dropbox link

loc_pre.csv dropbox link

至于loc_locate,它有点难以显示dataframes列表重复的例子。

一些先前确定的数据:

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,4889,4850,4851,4852中的第6个位置。在这种情况下,位置是4849.

按照这条逻辑,我想创建一个新的列表score_loc 1874个列表元素,它将显示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 
} 
+0

关于'locate'中的'Score'值,它来自'csv_t'。另外,请考虑使用'dput'显示示例,因为它会更容易复制/粘贴 – akrun

+0

是的,我会在后面更加清晰 – ALKI

+0

我为'loc_pre'和'csv_t'添加了一些dropbox链接 – ALKI

一种方式做到这一点是使用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 

注:我在这个例子中,我随机生成了我的分数