【问题标题】:How to perform function on a list of dataframes如何在数据框列表上执行功能
【发布时间】:2015-11-17 08:33:28
【问题描述】:

我有一个如下的数据框列表(即使 head=1,dput 也太大了,所以我不得不在这里用 str(df_list) 做一个模型)

$ OC_AH_026C  :'data.frame':    13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 45.183 111.038 162.785 -0.712 83.473 ...
 $ OC_AH_026C.1:'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 69.6 125.1 156.4 12.8 97.4 ...
 $ OC_AH_026T  :'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 13 12.5 103.1 56.7 145.4 ...
 $ OC_AH_058T  :'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 87.114 118.963 184.31 -0.173 171.733 ...
 $ OC_AH_084T  :'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 29.111 103.142 57.476 -0.712 50.156 ...
 $ OC_AH_086T  :'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 49.8 81 111.5 47 98.8 ...
 $ OC_AH_088T  :'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 117 152 224 121 196 ...
 $ OC_AH_096T  :'data.frame':   13081 obs. of  3 variables:
  ..$ chr    : num [1:13081] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ leftPos: num [1:13081] 736092 818159 4105086 4140849 4464314 ...
  ..$ Means  : num [1:13081] 49.5 102.8 93.6 15.2 103.2 ...

我正在尝试计算每个数据帧第三列中每一列的所有显着分数(使用 dplyr 分组到 bin 中的平均值),如果它们显着升高,它们被归为 1 ,显着降低为 -1 并且两者都没有,a每个数据框的新列为零。

为了进行分组,我已经完成了以下工作,效果很好:

CLL <- function (col) {
col <- col %>%
  group_by(chr, binnum = (leftPos) %/% 500000) %>%
  summarise(Means = mean(Means)) %>%
  mutate(leftPos = (binnum+1) * 120000) %>%
  select(leftPos, Means)}

CML<-lapply(df_list, CLL)

然后我坚持计算每个数据帧中每个平均值列的上限和下限。我认为这是因为我不知道如何引用此列,因为它位于数据框列表中。对于我使用的非列表数据框:

UL = median(col2, na.rm = TRUE) + alpha*IQR(col2[1], na.rm = TRUE)
LL = median(col2, na.rm = TRUE) - alpha*IQR(col2, na.rm = TRUE)

我尝试如下引用每个数据框的第三列:

tre<-lapply(CML, "[[", 3)

当然,这会提取第三列并将其放在“tre”中,而我想更改列表中的数据框,以便第三列与其他两列保持关系。

所以...... a)我如何引用平均值列并获取每个数据帧的上限和下限,然后 b)基于每个数据帧的平均值列中的行是否>上限或

【问题讨论】:

  • 我的第一步是library(data.table); DT &lt;- rbindlist(df_list, idcol = TRUE),但我不是 dplyr 用户。但是,那时您将不需要lapply,即使使用 dplyr,在绑定 data.frames 后,您的操作也应该更简单、更高效。
  • 谢谢罗兰。我非常热衷于弄清楚如何计算这个嵌套数据框,而不是将其转换为数据表。我可以明白为什么这很有用,并且可能会在稍后的解决方案中使用它
  • 你知道如何在 lapply 调用中编写匿名函数吗?我想这就是你所追求的。沿着lapply(data, function(x) {...}) 和...的行,您可以将 x 视为普通的 data.frame
  • 不知道怎么写。我试过: lapply(df_list, function(col2) {UL = median(col2, na.rm = TRUE) + alphaIQR(col2, na.rm = TRUE) LL = median(col2, na.rm = TRUE ) - alphaIQR(col2, na.rm = TRUE)}) 但刚刚被告知“错误:总结期间出错:需要数字数据”。我再次认为问题在于我不知道如何引用嵌套数据框中的列。也许我在这里没有理解一些重要的东西......
  • 您的col2 从哪里获得?还是其他功能?

标签: r


【解决方案1】:

这是你可以做的,类似于@Roland的回答。

假设您有如下所示的数据(您显示的数据的简化版本):

df_list <- list(OC_AH_026C = data.frame(chr = 1, 
                                        leftPos= c(73, 81, 41, 44),
                                        Means = c(111, 111, 162, -0.7)),
                OC_AH_026C.1 = data.frame(chr = 1,
                                          leftPos = c(73, 81, 41, 44),
                                          Means = c(69, 125, 156, 12)))

您可以使用lapply 像这样“循环”列表的元素,计算输入的 UL 和 LL(默认为“leftPos”),此外,它计算二进制列(res ) 表示Means-value 是否在置信区间之外:

df_list2 <- lapply(df_list, function(df, alpha, col2) { 

  # perform all your calculations here
  df$LL <- median(df[, col2], na.rm = T) - alpha*IQR(df[, col2], na.rm = T)
  df$UL <- median(df[, col2], na.rm = T) + alpha*IQR(df[, col2], na.rm = T)

  # -1 if Means < LL, 
  # 1 if Means > UL
  # 0 otherwise, nest the operators 
  # if you wish to calculate more complex conditions
  df$res <- 0 + ((df$Means < df$LL)*(-1)) + ((df$Means > df$UL)*1)

  return(df)
}, alpha = 0.95, col2 = "Means")

df_list2
# $OC_AH_026C
# chr leftPos Means       LL       UL res
# 1   1      73 111.0 72.35875 149.6412   0
# 2   1      81 111.0 72.35875 149.6412   0
# 3   1      41 162.0 72.35875 149.6412   1
# 4   1      44  -0.7 72.35875 149.6412  -1
# 
# $OC_AH_026C.1
# chr leftPos Means   LL    UL res
# 1   1      73    69 22.9 171.1   0
# 2   1      81   125 22.9 171.1   0
# 3   1      41   156 22.9 171.1   0
# 4   1      44    12 22.9 171.1  -1

(我希望我的问题是正确的,否则请告诉我,我会更正答案)。

data.table方式

为了完整起见,我引入了一个data.table-way,它更快(但摆脱了列表结构)。该方法如下所示:

library(data.table)
library(magrittr) # for some piping

# combine all listed data.frames to one data.table with another column, which indicates the name
dt <- lapply(1:length(df_list), function(i) {
  nam <- names(df_list)[i]
  df <- df_list[[i]]
  tmpdt <- data.table(name = nam, df)
}) %>% rbindlist

# calculate the limits
alpha = 0.95
dt[, LL := median(Means, na.rm = T) - alpha*IQR(Means, na.rm = T), by = name]
dt[, UL := median(Means, na.rm = T) + alpha*IQR(Means, na.rm = T), by = name]

dt[, res := 0 + ((df$Means < df$LL)*(-1)) + ((df$Means > df$UL)*1)]

【讨论】:

  • 好的,差不多了。只有
  • 所以你想在 Means UL 的情况下得到 1?!
  • 嗨。如果>UL,我希望得到1,如果
  • 好的,马上编辑。第二个问题,您是要计算MeansleftPos 还是第三个列的 CI?
  • CI 超过了手段。我已经在我的代码中更改了它,但猜你可能会将它合并到编辑中
猜你喜欢
  • 2022-07-06
  • 1970-01-01
  • 2021-09-06
  • 2021-02-20
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多