【问题标题】:ranking multiple data frames and summing across them in R在 R 中对多个数据帧进行排序并对其求和
【发布时间】:2013-03-21 08:39:00
【问题描述】:

我有 10 个数据帧,每个数据帧有 2 列,我将数据帧称为 a、b、c、d、e、f、g、h、i 和 j。

对于序列,每个数据帧中的第一列称为 s,对于每个序列对应的 p 值,第二列称为 p。 s 列包含所有 10 个数据帧的相同序列,本质上唯一的区别在于 p 值。 下面是数据框 a 的简短版本,有 600,000 行。

s       p
gtcg    0.06
gtcgg   0.05
gggaa   0.07
cttg    0.05

我想按 p 值对每个数据帧进行排名,最小的 p 值应该得到 1 的等级,相等的 p 值应该得到相同的等级。每个最终数据帧应采用以下格式:

    s       p_rank_a
    gtcg    2
    gtcgg   1
    gggaa   3
    cttg    1

我用这个来做一个:

r

cbind(a$s,r)

但我对循环不是很熟悉,也不知道如何自动执行此操作。最终,我想要一个具有 s 列的最终文件,在下一列中是每个特定序列的所有数据帧中所有等级的等级总和。 所以基本上是这样的:

s       ranksum_P_a-j
gtcg    34
gtcgg   5
gggaa   5009093
cttg    499

请帮忙,谢谢!

【问题讨论】:

  • gggaa 的排名不应该是 4 而不是 3?

标签: r sum ranking data-manipulation


【解决方案1】:

我会将所有data.frames 放入list,然后使用lapplytransform,如下所示:

my_l <- list(a,b,c) # all your data.frames
# you can use rank but it'll give you the average in case of ties
# lapply(my_l, function(x) transform(x, rank_p = rank(p)))

# I prefer this method instead
my_o <- lapply(my_l, function(x) transform(x, p = as.numeric(factor(p))))

# now bind them in to a single data.frame
my_o <- do.call(rbind, my_o)

# now paste them
aggregate(data = my_o, p ~ s, function(x) paste(x, collapse=","))

#       s     p
# 1  cttg 1,1,1
# 2 gggaa 3,3,3
# 3  gtcg 2,2,2
# 4 gtcgg 1,1,1

编辑,因为您要求提供一种可能更快的解决方案(由于数据量大),我建议像@Ricardo 一样,使用data.table 解决方案:

require(data.table)
# bind all your data.frames together
dt <- rbindlist(my_l) # my_l is your list of data.frames

# replace p-value with their "rank"
dt[, p := as.numeric(factor(p))]

# set key
setkey(dt, "s")

# combine them using `,`
dt[, list(p_ranks = paste(p, collapse=",")), by=s]

试试这个:

【讨论】:

  • 再次感谢您。我会将它与您回答的另一个一起使用并将它们结合起来。这些数据帧有 600,000 到 240 万行长,你知道我可以使用更快的程序吗?我对python有点了解,但仅此而已
【解决方案2】:

对于单个 data.frame,您可以一行完成,如下所示:
感谢@Arun 指出使用as.numeric(factor(p))

library(data.table)
aDT <- data.table(a)[, p_rank := as.numeric(factor(p))]

我建议将所有 data.frames 保存在一个列表中,以便您可以轻松地迭代它们。 由于您的 date.frames 是字母,因此很容易收集其中的十个:

# collect them all
allOfThem <- lapply(letters[1:10], get, envir=.GlobalEnv)   
# keep in mind you named an object `c`

# convert to DT and create the ranks
allOfThem <- lapply(allOfThem, function(x) data.table(x)[, p_rank := as.numeric(factor(p))])

另外说明:开始避免在R 中命名对象“c”和其他常用函数可能是一个好习惯。否则,你会发现你会开始遇到许多“无法解释”的行为,在你击败你的 碰壁了一个小时试图调试它,你意识到你已经覆盖了一个函数的名称。 这从未发生在我身上:)

【讨论】:

  • 我不确定order(rank(p)) 是否是这里想要的。例如:如果p=c(0.06, 0.05, 0.07, 0.05),则rank(p) = c(3, 1.5, 4, 1.5)order(.) = 2,4,1,3,而期望的结果是2,1,3,1。而order(p)order(rank(p)) 相同
  • @Arun,你是绝对正确的。在我的脑海中,我在想floor(rank(p)),但即使这样也不完全正确。我已经编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 1970-01-01
  • 2012-07-20
相关资源
最近更新 更多