【问题标题】:R creating new list from other lists/dataframesR从其他列表/数据框创建新列表
【发布时间】:2015-08-15 10:40:22
【问题描述】:

我计划简化这个问题,但为了清楚起见,我决定只发布我的原始代码。我正在尝试创建一个列表score_loc,它有1874 个列表元素并从三个不同的数据集中提取数据: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、4848、4849、4850、4851、4852 中的第 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
}

【问题讨论】:

  • 关于locate中的Score值,是不是来自csv_t。另外,请考虑使用dput 显示示例,因为它会更容易复制/粘贴
  • 是的,我会在帖子中说得更清楚
  • 我为loc_precsv_t添加了一些Dropbox链接
  • 谢谢,这是一个大数据集。抱歉,我的下载有限制。
  • @Chani - 在您的示例中,您说您想要 4844、4845、4846、4847、4848、4849、4850、4851、4852 的第 6 位,即 4850。不是 4849 吗?还是我只是还没有喝足够的咖啡? :\

标签: r for-loop


【解决方案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

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

【讨论】:

    猜你喜欢
    • 2015-04-21
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多