【问题标题】:How to apply functions in columns for data frames with different sizes in nested list?如何在嵌套列表中为不同大小的数据框应用列中的函数?
【发布时间】:2014-02-24 22:02:56
【问题描述】:

在 R 中,要将某些函数应用于列,您可以:

df$col <- someFunction(df$col)

现在我的问题是,当您在嵌套列表中有数据框时,您如何执行类似的任务? 假设我有一个像这样的以下列表,其中我在根目录的第二级中有数据框。

                                           +------+------+
                                  type1    | id   | name |
                              +----------->|------|------|
                              |            |      |      |
                              |            |      |      |
                year1         |            +------+------+
           +------------------+
           |                  |
           |                  |            +------+------+-----+
           |                  |  type2     | meta1|meta2 | name|
           |                  +----------> |------|------|-----|
           |                               |      |      |     |
           +                               +------+------+-----+
           |                     type1    +------+------+
           |                  +---------> | id   |name  |
           |                  |           |------|------|
           |     year2        |           |      |      |
   list    +----------------->+           |      |      |
           +                  |           +------+------+
           |                  |  type2     +------+------+-----+
           |                  +--------->  | meta1|meta2 |name |
           |                               |------|------|-----|
           |                               |      |      |     |
           |                    type1      +------+------+-----+
           |                 +---------->  +------+------+
           |                 |             | id   |name  |
           |     year3       |             |------|------|
           +-----------------+             |      |      |
                             |             |      |      |
                             |  type2      +------+------+
                             +---------->  +------+------+-----+
                                           |meta1 | meta2|name |
                                           |------|------|-----|
                                           |      |      |     |
                                           +------+------+-----+

我想用一些函数修改叶子中每个数据框中的“名称”列并将结果存储在那里。你是怎么做到的?

这是示例数据:

data<-list()

data$yr2001$type1 <- df_2001_1 <- data.frame(index=1:3,name=c("jack","king","larry"))
data$yr2001$type2 <- df_2001_2 <- data.frame(index=1:5,name=c("man","women","oliver","jack","jill"))
data$yr2002$type1 <- df_2002_1 <- data.frame(index=1:3,name=c("janet","king","larry"))
data$yr2002$type2 <- df_2002_2 <- data.frame(index=1:5,name=c("alboyr","king","larry","rachel","sam"))
data$yr2003$type1 <- df_2003_1 <- data.frame(index=1:3,name=c("dan","jay","zang"))
data$yr2003$type2 <- df_2003_2 <- data.frame(index=1:5,name=c("zang","king","larry","kim","fran"))

假设我想将列表中存储的每个数据框的名称列中的所有名称都大写

【问题讨论】:

  • 请发布您的数据的代表性样本。
  • 我的一般建议是不要以这种方式组织您的数据。在我看来,您在这里拥有的是两个(或可能只有一个)未融合的数据框。

标签: r nested plyr


【解决方案1】:

我同意上面@joran 的评论——这是乞求通过将类型添加为列来合并。但这是rapply 的一种方式。这假定name 列是每个嵌套data.frame 中唯一的factor 列。正如@josilber 的回答,我选择的函数是toupper

rapply(data, function(x) toupper(as.character(x)), classes='factor', how='replace')

这将删除data.frame 类,但保留了基本结构。如果您的姓名列已经是character,那么您将使用。

rapply(data, toupper, classes='character', how='replace')

【讨论】:

    【解决方案2】:

    为了说明(使用您的简化示例):

    library(reshape2)
    dat1 <- melt(data,id.vars = c("index","name"))
    > dat1$NAME <- toupper(dat1$name)
    

    【讨论】:

    • 我最终使用了这个解决方案,尽管它没有直接回答我提出的问题(与使用 lapply 的其他解决方案相比,我赞成)。你是对的,通过这种方式组织数据,它解决了所有下游问题并使分析变得容易。就好像我要一匹更快的马,你给了我一辆汽车
    【解决方案3】:

    您可以将lapply 函数嵌套两次以获取内部数据框。在这里,我将toupper 应用于每个name 变量:

    result <- lapply(data, function(x) {
      lapply(x, function(y) {
        y$name = toupper(y$name)
        return(y)
      })
    })
    result
    
    # $yr2001
    # $yr2001$type1
    #   index  name
    # 1     1  JACK
    # 2     2  KING
    # 3     3 LARRY
    # 
    # $yr2001$type2
    #   index   name
    # 1     1    MAN
    # 2     2  WOMEN
    # 3     3 OLIVER
    # 4     4   JACK
    # 5     5   JILL
    # 
    # 
    # $yr2002
    # $yr2002$type1
    #   index  name
    # 1     1 JANET
    # 2     2  KING
    # 3     3 LARRY
    # 
    # $yr2002$type2
    #   index   name
    # 1     1 ALBOYR
    # 2     2   KING
    # 3     3  LARRY
    # 4     4 RACHEL
    # 5     5    SAM
    # 
    # 
    # $yr2003
    # $yr2003$type1
    #   index name
    # 1     1  DAN
    # 2     2  JAY
    # 3     3 ZANG
    # 
    # $yr2003$type2
    #   index  name
    # 1     1  ZANG
    # 2     2  KING
    # 3     3 LARRY
    # 4     4   KIM
    # 5     5  FRAN
    

    【讨论】:

    • josilber,也许我误解了,但这真的是递归的,还是只有两个嵌套循环?另外,我希望你不介意我在我的例子中借用toupper
    • 谢谢——更新了措辞。当然,toupper 借用很好:)
    【解决方案4】:

    这是一个基于lapply 的真正递归版本(即可以使用更深的嵌套),并且除了您拥有的唯一类型的终端叶子是数据帧之外,不做任何其他假设。不幸的是,rapply 不会停止 data.frames 的递归,所以如果你想对数据帧进行操作,你必须使用lapply(否则 Matthew 的答案是完美的)。

    samp.recur <- function(x) 
      lapply(x, 
        function(y) 
          if(is.data.frame(y)) transform(y, name=toupper(name)) else samp.recur(y))
    

    这会产生:

    samp.recur(data)
    # $yr2001
    # $yr2001$type1
    #   index  name
    # 1     1  JACK
    # 2     2  KING
    # 3     3 LARRY
    
    # $yr2001$type2
    #   index   name
    # 1     1    MAN
    # 2     2  WOMEN
    # 3     3 OLIVER
    # 4     4   JACK
    # 5     5   JILL
    
    # etc...
    

    虽然我也同意其他人的观点,但您可能需要考虑重新构建您的数据。

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 2018-03-21
      • 1970-01-01
      • 2021-09-06
      • 2017-11-15
      • 2022-12-05
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      相关资源
      最近更新 更多