【问题标题】:Applying a function recursively over a list在列表上递归地应用函数
【发布时间】:2015-06-16 09:34:15
【问题描述】:

我正在尝试使用 lapply 和包含多个 for 循环的手工函数将向量的值应用于字符向量列表。啊!基本上我所拥有的是一个看起来像这样的字符向量列表(filename_lists3):

$`809`
[1] "rakelib/blueprint.rb"          "projects/daedalus/daedalus.rb"

$`859`
[1] "README"
...

还有一个如下所示的命名数字向量 (degree_list):

projects/daedalus/daedalus.rb          rakelib/blueprint.rb 
                        1                             5 
                   README                  README.mdown 
                        6                             1 
...

我要做的是将filename_list3中的字符串与names(degree_list)中的字符串进行匹配,当它们相同时,将filename_list3中的字符串替换为degree_list中的整数。

这是我的代码:

dput(filename_lists3[1:10])

structure(list(`809` = c("rakelib/blueprint.rb", "projects/daedalus/daedalus.rb"
), `859` = "README", `957` = "spec/debugger/spec_helper.rb", 
`1007` = c("README.mdown", "README"), `1038` = "spec/ruby/core/file/stat/setgid_spec.rb", 
`1099` = c("vm/test/test_embedding.hpp", "vm/embed.c", "vm/api/embed.h"
), `1179` = c("vm/capi/module.cpp", "kernel/common/module19.rb", 
          "kernel/common/module18.rb"), `1235` = c("vm/builtin/thread.hpp", 
                                                   "vm/builtin/thread.cpp", "kernel/common/thread.rb", "kernel/bootstrap/thread.rb"
          ), `1390` = "spec/ruby/core/marshal/dump_spec.rb", `1422` = c("spec/tags/19/ruby/core/module/constants_tags.txt", 
                                                                        "kernel/common/module19.rb", "kernel/common/module18.rb", 
                                                                        "kernel/common/module.rb")), .Names = c("809", "859", "957", 
                                                                                                                "1007", "1038", "1099", "1179", "1235", "1390", "1422"))

dput(degree_list[1:10])

structure(c(1, 5, 6, 1, 2, 2, 2, 5, 7, 2), .Names = c("projects/daedalus/daedalus.rb", 
                                                  "rakelib/blueprint.rb", "README", "README.mdown", "vm/api/embed.h", 
                                                  "vm/embed.c", "vm/test/test_embedding.hpp", "kernel/common/module18.rb", 
                                                  "kernel/common/module19.rb", "vm/capi/module.cpp"))

以及函数和 lapply 调用:

insert_sna_stat <- function(x, input = degree_list){
  for (i in 1:length(x)){
    for (n in 1:length(input))
      if (names(input)[n] == x[i])
        x[i] <- input[n] else 
      x[i] <- x[i]
  }
}

lapply(filename_lists3, insert_sna_stat)

此时只会生成 null。这里出了什么问题?如何修改它以执行我上面描述的操作?

【问题讨论】:

    标签: r lapply data-manipulation


    【解决方案1】:

    你可以使用rapply:

    > rapply(filename_lists3, function(x) ifelse(x %in% names(degree_list), degree_list[x], x), how='replace')
    $`809`
    [1] 5 1
    
    $`859`
    [1] 6
    
    $`957`
    [1] "spec/debugger/spec_helper.rb"
    
    $`1007`
    [1] 1 6
    
    $`1038`
    [1] "spec/ruby/core/file/stat/setgid_spec.rb"
    
    $`1099`
    [1] 2 2 2
    
    $`1179`
    [1] 2 7 5
    
    $`1235`
    [1] "vm/builtin/thread.hpp"      "vm/builtin/thread.cpp"     
    [3] "kernel/common/thread.rb"    "kernel/bootstrap/thread.rb"
    
    $`1390`
    [1] "spec/ruby/core/marshal/dump_spec.rb"
    
    $`1422`
    [1] "spec/tags/19/ruby/core/module/constants_tags.txt"
    [2] "7"                                               
    [3] "5"                                               
    [4] "kernel/common/module.rb"  
    

    【讨论】:

      【解决方案2】:

      您可以lapply 覆盖您的文件名列表,并使用这些值对学位列表进行子集化。如果没有匹配,你会得到 NA,所以在这种情况下环绕并ifelse 返回原始值。

      lapply(filename_lists3, function(x) ifelse(is.na(degree_list[x]),x,degree_list[x]))
      $`809`
               rakelib/blueprint.rb projects/daedalus/daedalus.rb 
                                  5                             1 
      
      $`859`
      README 
           6 
      
      $`957`
                                <NA> 
      "spec/debugger/spec_helper.rb" 
      
      $`1007`
      README.mdown       README 
                 1            6 
      
      $`1038`
                                           <NA> 
      "spec/ruby/core/file/stat/setgid_spec.rb" 
      
      $`1099`
      vm/test/test_embedding.hpp                 vm/embed.c 
                               2                          2 
                  vm/api/embed.h 
                               2 
      
      $`1179`
             vm/capi/module.cpp kernel/common/module19.rb kernel/common/module18.rb 
                              2                         7                         5 
      
      $`1235`
                              <NA>                         <NA> 
           "vm/builtin/thread.hpp"      "vm/builtin/thread.cpp" 
                              <NA>                         <NA> 
         "kernel/common/thread.rb" "kernel/bootstrap/thread.rb" 
      
      $`1390`
                                       <NA> 
      "spec/ruby/core/marshal/dump_spec.rb" 
      
      $`1422`
                                                    <NA> 
      "spec/tags/19/ruby/core/module/constants_tags.txt" 
                               kernel/common/module19.rb 
                                                     "7" 
                               kernel/common/module18.rb 
                                                     "5" 
                                                    <NA> 
                               "kernel/common/module.rb"
      

      【讨论】:

        【解决方案3】:

        你可以使用match函数:

        res <- lapply(filename_lists3, function(x){
          m <- match(x,names(degree_list))
          x[!is.na(m)] <- degree_list[m[!is.na(m)]]
          return(x)
        })
        
        ##### results
        > res
        $`809`
        [1] "5" "1"
        
        $`859`
        [1] "6"
        
        $`957`
        [1] "spec/debugger/spec_helper.rb"
        
        $`1007`
        [1] "1" "6"
        
        $`1038`
        [1] "spec/ruby/core/file/stat/setgid_spec.rb"
        
        $`1099`
        [1] "2" "2" "2"
        
        $`1179`
        [1] "2" "7" "5"
        
        $`1235`
        [1] "vm/builtin/thread.hpp"      "vm/builtin/thread.cpp"      "kernel/common/thread.rb"    "kernel/bootstrap/thread.rb"
        
        $`1390`
        [1] "spec/ruby/core/marshal/dump_spec.rb"
        
        $`1422`
        [1] "spec/tags/19/ruby/core/module/constants_tags.txt" "7"                                               
        [3] "5"                                                "kernel/common/module.rb"  
        

        【讨论】:

          【解决方案4】:

          我认为你最好在这里使用merge。但是,首先您应该将列表转换为 data.frames。

          D1 <- do.call(rbind,lapply(seq_along(filename_lists),
                       function(i) data.frame(name=filename_lists[[i]],
                                              id  = names(filename_lists)[i])))
          
          D2 <- as.data.frame(degree_list)
          D2$name <- rownames(D2)
          
          merge(D1,D2,all.x=TRUE)
          
          #                                                name   id degree_list
          # 1                     projects/daedalus/daedalus.rb  809           1
          # 2                              rakelib/blueprint.rb  809           5
          # 3                                            README  859           6
          # 4                                            README 1007           6
          # 5                      spec/debugger/spec_helper.rb  957          NA
          # 6                                      README.mdown 1007           1
          # 7           spec/ruby/core/file/stat/setgid_spec.rb 1038          NA
          # 8                                    vm/api/embed.h 1099           2
          # 9                                        vm/embed.c 1099           2
          # 10                       vm/test/test_embedding.hpp 1099           2
          # 11                        kernel/common/module18.rb 1179           5
          # 12                        kernel/common/module18.rb 1422           5
          # 13                        kernel/common/module19.rb 1179           7
          # 14                        kernel/common/module19.rb 1422           7
          # 15                               vm/capi/module.cpp 1179           2
          # 16                       kernel/bootstrap/thread.rb 1235          NA
          # 17                          kernel/common/thread.rb 1235          NA
          # 18                            vm/builtin/thread.cpp 1235          NA
          # 19                            vm/builtin/thread.hpp 1235          NA
          # 20              spec/ruby/core/marshal/dump_spec.rb 1390          NA
          # 21                          kernel/common/module.rb 1422          NA
          # 22 spec/tags/19/ruby/core/module/constants_tags.txt 1422          NA
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-01
            • 2016-05-17
            • 2023-03-29
            相关资源
            最近更新 更多