R从其他列表/数据框中创建新列表
问题描述:
我计划简化这个问题,但我决定只发布我的原始代码以便清晰。我试图创建一个列表score_loc
,其中包含1874个列表元素,并从三组不同的数据中提取数据:loc_pre
,loc_locate
和csv_t
。为了创建这个列表,我没有有效地使用for循环来为每个列表元素分配数据帧,这是非常缓慢的,因为数据非常大,给我错误。R从其他列表/数据框中创建新列表
重复性的数据
Shortened csv_t.csv包含第一20000行
至于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
}
答
一种方式做到这一点是使用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
注:我在这个例子中,我随机生成了我的分数
关于'locate'中的'Score'值,它来自'csv_t'。另外,请考虑使用'dput'显示示例,因为它会更容易复制/粘贴 – akrun
是的,我会在后面更加清晰 – ALKI
我为'loc_pre'和'csv_t'添加了一些dropbox链接 – ALKI