【问题标题】:using lapply function and list in r在 r 中使用 lapply 函数和列表
【发布时间】:2017-12-16 15:03:54
【问题描述】:
d1 <- data.frame(col_one = c(1,2,3),col_two = c(4, 5, 6))
d2 <- data.frame(col_one = c(1, 1, 1), col_two = c(6, 5, 4))
d3 <- data.frame(col_one = c(7, 1, 1), col_two = c(8, 5, 4))
my.list <- list(d1, d2,d3)

for (i in 1:3) {
  table<- lapply(my.list, function(data, count) {
    sql <-
      #sqldf(
        paste0(
          "select *,count(col_one) from data where col_one = ",
          count," group by col_one"
        )
      #)
    print(sql)
  },
  count = i)
}

输出:

[1] "select *,count(col_one) from data where col_one = 1 group by col_one"
[1] "select *,count(col_one) from data where col_one = 1 group by col_one"
[1] "select *,count(col_one) from data where col_one = 1 group by col_one"
[1] "select *,count(col_one) from data where col_one = 2 group by col_one"
[1] "select *,count(col_one) from data where col_one = 2 group by col_one"
[1] "select *,count(col_one) from data where col_one = 2 group by col_one"
[1] "select *,count(col_one) from data where col_one = 3 group by col_one"
[1] "select *,count(col_one) from data where col_one = 3 group by col_one"
[1] "select *,count(col_one) from data where col_one = 3 group by col_one"

期望:

[1] "select *,count(col_one) from data where col_one = 1 group by col_one"
[1] "select *,count(col_one) from data where col_one = 2 group by col_one"
[1] "select *,count(col_one) from data where col_one = 3 group by col_one"

我该如何改进?我希望运行 SQL 来创建我想要的新数据集,但它不成功,我可以指定知道与 SQL 语句相关的列表的索引。还有其他简单的方法吗?

我已经尝试过其中一种方法。

d1 <- data.frame(col_one = c(1,2,3),col_two = c(4, 5, 6))
d2 <- data.frame(col_one = c(3, 2, 1), col_two = c(6, 5, 4))
d3 <- data.frame(col_one = c(7, 2, 1), col_two = c(8, 5, 4))
my.list <- list(d1, d2,d3)
seq_along(x)
#for (i in 1:3) {
  table<- lapply(seq_along(my.list), function(index) {
    sql <-
      sqldf(
        paste0(
          "select *,count(col_one) from my.list where col_one = ",
          index," group by col_one"
        )
      )
    print(sql)
  })
#}

输出:

[1] "select *,count(col_one) from my.list where col_one = 1 group by col_one"
[1] "select *,count(col_one) from my.list where col_one = 2 group by col_one"
[1] "select *,count(col_one) from my.list where col_one = 3 group by col_one"

但是,它不会找到要运行 SQL 的数据集。

d1 <- data.frame(col_one = c(1,2,3),col_two = c(4, 5, 6))
d2 <- data.frame(col_one = c(1, 1, 1), col_two = c(6, 5, 4))
d3 <- data.frame(col_one = c(7, 1, 1), col_two = c(8, 5, 4))
my.list <- list(d1, d2,d3)
table<- mapply(function(data, count) {
  sql <-
    sqldf(
    paste0(
      "select *,count(col_one) from data where col_one = ",
      count," group by col_one"
    )
  )
  print(sql)
}, my.list, 1
)

【问题讨论】:

  • 您是否尝试将所有数据帧的行与my.list 中索引的附加列以及每个数据帧的行数绑定在一起? do.call("rbind", lapply(seq_along(my.list), function(i) cbind(Index = i, Count = nrow(my.list[[i]]), my.list[[i]])))

标签: r apply lapply


【解决方案1】:

如果我理解正确,OP 想为my.list 中的每个 data.frames 为col_one 创建列联表,即他想知道每个值 1、2 或 3 的次数出现在每个data.frame中的col_one中。

正如my answeranother question of the OP 中的解释以及G. Grothendieck 所建议的那样,在大型data.table 中将具有相同结构 的data.frames 组合起来几乎总是比保留它们在列表中分开。顺便说一句,OP 还有第三个question ("how to loop the dataframe using sqldf?") 寻求有关data.frames 列表的帮助。

为了在一个大的 data.table 中组合 data.frames,使用了rbindlist() 函数。请注意,添加的 id 列 df 标识了每一行的原始 data.frame。

library(data.table)
rbindlist(my.list, idcol = "df")
   df col_one col_two
1:  1       1       4
2:  1       2       5
3:  1       3       6
4:  2       1       6
5:  2       1       5
6:  2       1       4
7:  3       7       8
8:  3       1       5
9:  3       1       4

现在我们可以轻松计算聚合:

rbindlist(my.list, idcol = "df")[, count_col_one := .N, by = .(df, col_one)][]
   df col_one col_two count_col_one
1:  1       1       4             1
2:  1       2       5             1
3:  1       3       6             1
4:  2       1       6             3
5:  2       1       5             3
6:  2       1       4             3
7:  3       7       8             1
8:  3       1       5             2
9:  3       1       4             2

data.table 语句使用特殊符号.N 并按dfcol_one 分组,计算每个dfcol_one 中的每个单独值的出现次数。

在问题中,OP 只要求计算 col_one 中出现 1、2 或 3 的次数。如果这确实是有意的,则需要删除 7 的值。这可以通过过滤结果来完成:

rbindlist(my.list, idcol = "df")[, count_col_one := .N, by = .(df, col_one)][
  col_one %in% 1:3]

【讨论】:

    【解决方案2】:

    您需要同时迭代datacounts。在tidyverse 中,我建议使用 purrr::map2(),但在基础 R 中,您可以简单地这样做:'

    table<- mapply(function(data, count) {
        sql <-
          #sqldf(
          paste0(
            "select *,count(col_one) from data where col_one = ",
            count," group by col_one"
          )
        #)
        print(sql)
      }, my.list, 1:3
      )
    [1] "select *,count(col_one) from data where col_one = 1 group by col_one"
    [1] "select *,count(col_one) from data where col_one = 2 group by col_one"
    [1] "select *,count(col_one) from data where col_one = 3 group by col_one"
    

    【讨论】:

    • 感谢您的帮助。我已经学习了新功能,因为我不知道我应该寻找哪些关键字。如何指定包含相关值的列表索引?因为在运行 SQL 之后值是分开的。例如,运行 SQL 语句后,前三项应该是一个列表,以便将它们保存在一起。我编辑内容是因为我无法格式化评论中的代码。 @dmi3kno
    • 不确定我明白你的意思。请您尝试重述这个问题好吗?
    • 我编辑了这个问题,抱歉迟到了,因为我正在考虑如何表达这个问题。我可以让每个 SQL 语句成为一个数据框并列出一个列表吗?是二维列表吗?我是初学者。 @dmi3kno
    • 哦,我找到了解决方案。使用 SIMPLIFY = FALSE
    猜你喜欢
    • 2020-05-08
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 2015-10-12
    • 1970-01-01
    • 2020-04-04
    相关资源
    最近更新 更多