【问题标题】:Extracting outputs from lapply to a dataframe从 lapply 提取输出到数据帧
【发布时间】:2012-05-22 09:13:38
【问题描述】:

我有一些 R 代码,它使用以下代码对当前目录中的所有文件执行一些数据提取操作:

files <- list.files(".", pattern="*.tts")
results <- lapply(files, data_for_time, "17/06/2006 12:00:00")

lapply 的输出如下(使用dput() 提取)——基本上是一个充满向量的列表:

list(c("amer", "14.5"), c("appl", "14.2"), c("brec", "13.1"), 
c("camb", "13.5"), c("camo", "30.1"), c("cari", "13.8"), 
c("chio", "21.1"), c("dung", "9.4"), c("east", "11.8"), c("exmo", 
"12.1"), c("farb", "14.7"), c("hard", "15.6"), c("herm", 
"24.3"), c("hero", "13.3"), c("hert", "11.8"), c("hung", 
"26"), c("lizr", "14"), c("maid", "30.4"), c("mart", "8.8"
), c("newb", "14.7"), c("newl", "14.3"), c("oxfr", "13.9"
), c("padt", "10.3"), c("pbil", "13.6"), c("pmtg", "11.1"
), c("pmth", "11.7"), c("pool", "14.6"), c("prae", "11.9"
), c("ral2", "12.2"), c("sano", "15.3"), c("scil", "36.2"
), c("sham", "12.9"), c("stra", "30.9"), c("stro", "14.7"
), c("taut", "13.7"), c("tedd", "22.3"), c("wari", "12.7"
), c("weiw", "13.6"), c("weyb", "8.4"))

但是,我想将此输出作为包含两列的数据框处理:一列用于字母代码("amer""appl" 等),另一列用于数字(14.514.2 等)。

不幸的是,as.data.frame 似乎不适用于列表中的嵌套向量输入。我应该如何进行转换?我是否需要更改函数data_for_time 返回其值的方式?目前它只返回c(name, value)。或者有没有一种很好的方法可以将这种输出转换为数据帧?

【问题讨论】:

  • 如果您使用sapply 而不是lapply,您可能会得到一个更“常规”的对象。

标签: r list dataframe


【解决方案1】:

如果results 是您的列表,试试这个:

> as.data.frame(do.call(rbind, results))

     V1   V2
1  amer 14.5
2  appl 14.2
3  brec 13.1
4  camb 13.5
...

【讨论】:

  • +1 -- do.call 在这里很优雅。我什至建议 OP 修改他的 data_for_time 函数以返回具有适当名称和类型的 data.frame。从而消除这里的as.data.frame调用和强制的风险。
【解决方案2】:

一种选择可能是使用 plyr 包中的 ldply 函数,它会为您将内容重新拼接到数据框中。

一个简单的使用示例:

ldply(1:10,.fun = function(x){c(runif(1),"a")})
                    V1 V2
1    0.406373084755614  a
2    0.456838687881827  a
3    0.681300171650946  a
4    0.294320539338514  a
5    0.811559669673443  a
6    0.340881009353325  a
7    0.134072444401681  a
8  0.00850683846510947  a
9    0.326008745934814  a
10    0.90791508089751  a

但请注意,如果您将变量类型与c() 混合使用,您可能希望更改您的函数以仅返回data.frame(name= name,value = value) 而不是c(name,value)。否则一切都会被强制转换成角色(就像我上面的例子一样)。

【讨论】:

    【解决方案3】:
    inp <- list(c("amer", "14.5"), c("appl", "14.2"), .... # did not see need to copy all
    
    data.frame( first= sapply( inp, "[", 1), 
                second =as.numeric( sapply( inp, "[", 2) ) )
    
       first second
    1   amer   14.5
    2   appl   14.2
    3   brec   13.1
    4   camb   13.5
    5   camo   30.1
    6   cari   13.8
    snipped output
    

    【讨论】:

      【解决方案4】:

      因为 Nelton 接受了我正在给予的回应,而 Joran 接受了我能想到的唯一其他合理的回应,因为我应该写一篇论文,所以这是一个荒谬的答案:

      #I named your list LIST
      LIST2 <-  LIST[[1]]
      lapply(2:length(LIST), function(i) {LIST2 <<- rbind(LIST2, LIST[[i]])})
      data.frame(LIST2)
      

      【讨论】:

      • +一个用于拖延亲和力... ;)
      猜你喜欢
      • 1970-01-01
      • 2014-08-13
      • 2020-02-18
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 1970-01-01
      相关资源
      最近更新 更多