【问题标题】:Adding differing chars to list of dataframes via lapply通过 lapply 向数据框列表添加不同的字符
【发布时间】:2019-01-25 13:48:36
【问题描述】:

我想将 char 向量的各个元素作为列添加到 data.frames 列表中。我可以手动完成,但有更优雅的 lapply 方式吗?

# Create sample dfs 
set.seed(1)
df1 <- data.frame("one" = sample(1:10,10,replace=TRUE),
                  "two" = sample(1:10,10,replace=TRUE))

df2 <- data.frame("three" = sample(1:10,10,replace=TRUE),
                  "four" = sample(1:10,10,replace=TRUE))

df3 <- data.frame("five" = sample(1:10,10,replace=TRUE),
                  "six" = sample(1:10,10,replace=TRUE))

# Combine them to list 
dflist = list("df1"=df1,"df2"=df2,"df3"=df3)

# add labelling column 
dflist$df1["label"] <- "a"
dflist$df2["label"] <- "b"
dflist$df3["label"] <- "c"

# With lapply I can only add either "a", "b" or "c" 
dflist = list("df1"=df1,"df2"=df2,"df3"=df3)
labvec <- c("a","b","c")
lapply(dflist,function(x) cbind(x,labvec[2])) # I have to select 1, 2 or 3.

问的不同:我也可以用 lapply 索引“labvec”吗?

【问题讨论】:

    标签: r list character lapply


    【解决方案1】:

    你可以使用Map

    Map(`[<-`, x = dflist, i = "label", value = labvec)
    #$df1
    #  one two label
    #1   1   3     a
    #2   2   1     a
    #3   2   3     a
    
    #$df2
    #  three four label
    #1     3    1     b
    #2     2    1     b
    #3     2    1     b
    
    #$df3
    #  five six label
    #1    3   2     c
    #2    2   3     c
    #3    3   3     c
    

    xivalue 是函数 `[&lt;-` 的参数,我们通常不会将其命名为 iris['Species2'] &lt;- "a_string_column",其中

    • x : iris
    • i'Species2'
    • value"a_string_column"

    与上面的想法相同,但这里我们使用一个带有三个参数的匿名函数(可能更容易阅读):

    Map(function(data, label, value) {data[label] <- value; data}, 
         data = dflist,
         label = "label",
         value = labvec) 
    

    数据

    set.seed(1)
    df1 <- data.frame("one" = sample(3,replace=TRUE),
                      "two" = sample(3,replace=TRUE))
    
    df2 <- data.frame("three" = sample(3,replace=TRUE),
                      "four" = sample(3,replace=TRUE))
    
    df3 <- data.frame("five" = sample(3,replace=TRUE),
                      "six" = sample(3,replace=TRUE))
    
    # Combine them to list 
    dflist = list("df1"=df1,"df2"=df2,"df3"=df3)
    

    【讨论】:

    • 谢谢,它有效,但我不明白为什么。不幸的是, Map() 的文档对我一点帮助都没有。
    • @Krisselack 很高兴它起作用了,是的,文档可能会更好,但您会在?mapply 找到更多信息。 Map 应用一个函数,这里是 "[&lt;-"' 与您通过 ... 指定的参数并行。一个更简单的例子(虽然不是很有用,但应该是Map("-", c(10, 5, 3), c(5, 3, 1))。从10 减去5.from 5 3 和从3 减去1Map 返回一个列表。
    • 这个例子我很容易理解,但是你的(更容易阅读)符号对我来说很难阅读。您首先定义函数:在那里创建 data$label 并为其赋值并返回(新的)数据。 ...在您的第一个解决方案中,您映射了函数“[
    • "...我什至不知道它存在" - 这就是为什么我认为第二种表示法更容易理解的原因。您可以通过help("[&lt;-") 阅读文档。您使用此功能的通常方式是my_data["column"] &lt;- value。有时,当您不想使用匿名时,这种“函数命名”很方便。与我之前评论中的示例相同,但这次使用匿名函数:Map(function(x, y) x - y, x = c(10, 5, 3), y = c(5, 3, 1))
    • @Krisselack 你觉得这很有帮助:adv-r.had.co.nz/Functions.html#all-calls
    【解决方案2】:

    使用lapply() 和使用dplyr::mutate() 的解决方案。

    library(dplyr)
    
    dflist <- lapply(1:length(dflist), function(i) {
      dflist[[i]] %>% 
        mutate(label = letters[i])
    })
    # lapply(dflist, head, 2)
    # [[1]]
    #   one two label
    # 1   3   3     a
    # 2   4   2     a
    # 
    # [[2]]
    #   three four label
    # 1    10    5     b
    # 2     3    6     b
    # 
    # [[3]]
    #   five six label
    # 1    9   5     c
    # 2    7   9     c
    

    请注意,这只是“强制”lapply(),我的意思是,它基本上是一个没有很好隐藏的 for 循环。

    【讨论】:

      【解决方案3】:

      tidyversemap2 一起使用

      library(tidyverse)
      map2(dflist, labvec, ~ .x %>% 
                            mutate(label = .y))
      #$df1
      #   one two label
      #1    3   3     a
      #2    4   2     a
      #3    6   7     a
      #4   10   4     a
      #5    3   8     a
      #6    9   5     a
      #7   10   8     a
      #8    7  10     a
      #9    7   4     a
      #10   1   8     a
      
      #$df2
      #   three four label
      #1     10    5     b
      #2      3    6     b
      #3      7    5     b
      #4      2    2     b
      #5      3    9     b
      #6      4    7     b
      #7      1    8     b
      #8      4    2     b
      #9      9    8     b
      #10     4    5     b
      
      #$df3
      #   five six label
      #1     9   5     c
      #2     7   9     c
      #3     8   5     c
      #4     6   3     c
      #5     6   1     c
      #6     8   1     c
      #7     1   4     c
      #8     5   6     c
      #9     8   7     c
      #10    7   5     c
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-06
        • 1970-01-01
        • 2022-01-20
        • 2018-02-15
        • 1970-01-01
        • 1970-01-01
        • 2015-04-23
        • 2016-07-07
        相关资源
        最近更新 更多