在R中合并一个数据框列表和另一个数据框列表的方法是将其中一个数据框列表展开后再与另一个数据框列表合并。

3
我该如何在R中处理包含多个数据框的两个列表?以下是示例数据:
set.seed(1)
set1 <- data.frame(NAME = paste("row_", 1:10, sep = ""),
                 SYMBOL = paste(c(sample(LETTERS, 10))),
                 SIGNIFICANT = sample(c("yes", "no"), 10, replace = TRUE))
set2 <- data.frame(NAME = paste("row_", 1:10, sep = ""),
               SYMBOL = paste(c(sample(LETTERS, 10))),
               SIGNIFICANT = sample(c("yes", "no"), 10, replace = TRUE))
set3 <- data.frame(NAME = paste("row_", 1:10, sep = ""),
                  SYMBOL = paste(c(sample(LETTERS, 10))),
                  SIGNIFICANT = sample(c("yes", "no"), 10, replace = TRUE))
set4 <- data.frame(NAME = paste("row_", 1:10, sep = ""),
                 SYMBOL = paste(c(sample(LETTERS, 10))),
                 SIGNIFICANT = sample(c("yes", "no"), 10, replace = TRUE))
files <- list(set1, set2, set3, set4)
names(files) <- paste("Set", 1:4, sep = "")
reports <- list(data.frame(SETS = c("Set1", "Set3"),
                        STATISTIC = runif(2)),
             data.frame(SETS = c("Set2", "Set4"),
                        STATISTIC = runif(2)))
names(reports) <- c("Report1", "Report2")

files 是一个包含许多来自分析的元数据数据帧的列表。

> files$Set1
     NAME SYMBOL SIGNIFICANT
1   row_1      Y          no
2   row_2      D          no
3   row_3      G          no
4   row_4      A         yes
5   row_5      B         yes
6   row_6      K         yes
7   row_7      N         yes
8   row_8      R         yes
9   row_9      W         yes
10 row_10      J         yes

reports 是一个包含两个数据框的列表,其中包含来自双向分析的主要输出和相关统计信息。

> reports$Report1
  SETS STATISTIC
1 Set1 0.4100841
2 Set3 0.8108702

请注意,files列表中的数据框名称与reports列表中的数据框第二列相对应。
我希望以特定方式折叠这些files元数据。如果files$Set1$SIGNIFICANT == 'yes',我想将相应的SYMBOL添加到逗号分隔的字符串中。然后,我想将该字符串附加到reports中的相应集合中。因此,我的期望输出如下:
> head(reports$Report1)
  SETS STATISTIC              SYMBOL
1 Set1 0.4100841 A, V, K, N, R, W, J
2 Set3 0.8108702          F, S, J, V

同样也适用于Report2

对于这个例子手动完成很容易,但在我的实际项目中,length(files)=600

我试图通过一个for循环来解析它,但总是遇到错误。这是我当前的迭代:

output <- data.frame()
for(i in 1:length(files)){
  for(j in 1:nrow(files[[i]])){
    if(files[j, 3] == "Yes"){
      output[i, 1]=i;
      output[i, 2]=paste0(i[,2], collapse = ", ")
    }
  }
}

我的当前错误:

Error in i[[j, 3]] : incorrect number of subscripts

我已经使用 R 4 年了,如果有一件事我知道的是,人们经常避免使用循环。我知道一些类似于 applylapply 等函数通常会让生活变得更加轻松。

3个回答

2
我认为您可以分两步完成此操作,首先创建一个数据框,其中包含每个集合的重要符号。在这里:
sigset <- stack(lapply(files, function(x) paste(x$SYMBOL[x$SIGNIFICANT=="yes"], collapse=", ")))
names(sigset) <- c("SYMBOL","SETS")

我们使用lapply()来迭代文件列表,提取重要的符号并将它们组合在一起,然后我们将列表堆叠成一个data.frame,以便更容易地处理。我们更改名称,以便更容易地按列名合并。然后,我们可以将此列表与每个报告合并。
output <- lapply(reports, function(x) merge(x, sigset))

2
你可以使用 sapply 来迭代每个数据框的 files 列,仅保留 SIGNIFICANT = 'yes' 值并将它们合并为一个字符串。
data <- stack(sapply(files,function(x) toString(x$SYMBOL[x$SIGNIFICANT=='yes'])))

data
#               values  ind
#1 A, B, K, N, R, W, J Set1
#2                B, F Set2
#3          F, S, J, V Set3
#4    W, Z, H, Q, D, M Set4

您可以使用merge函数将datareports中的每个dataframe合并。
result <- lapply(reports, function(x) merge(x,data, by.x = 'SETS', by.y = 'ind'))
result

#$Report1
#  SETS STATISTIC              values
#1 Set1 0.4100841 A, B, K, N, R, W, J
#2 Set3 0.8108702          F, S, J, V

#$Report2
#  SETS STATISTIC           values
#1 Set2 0.6049333             B, F
#2 Set4 0.6547239 W, Z, H, Q, D, M

1

这里有一个与MrFlick类似的解决方案,使用subsetsetNames和不同的lapply调用,可能更容易理解:

# get the characters with SIGNIFICANT equal to "yes"
all_symbs <- lapply(files, subset, SIGNIFICANT == "yes", SYMBOL, TRUE)
# create one data.frame with the above after concatenating
all_files <- setNames(stack(lapply(all_symbs, paste0, collapse = ", ")),
                      c("SYMBOL","SETS"))
# merge with reports
res <- lapply(reports, merge, y = all_files)
# the result
res
#R> $Report1
#R>   SETS STATISTIC              SYMBOL
#R> 1 Set1 0.4100841 A, B, K, N, R, W, J
#R> 2 Set3 0.8108702          F, S, J, V
#R> 
#R> $Report2
#R>   SETS STATISTIC           SYMBOL
#R> 1 Set2 0.6049333             B, F
#R> 2 Set4 0.6547239 W, Z, H, Q, D, M

您可以通过创建匿名函数来替换两个lapply(files, ...)lapply(all_symbs, ...)调用中的一个lapply调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接