【问题标题】:R: for-loops or lapply to some elements of a named listR:for循环或应用于命名列表的某些元素
【发布时间】:2020-04-23 14:47:08
【问题描述】:

例如,我有一个带有模型参数的config.R 文件,如下所示:

var1 = "Fruit"
var2 = "Vegetables"
country = c("BRAZIL", "ECUADOR", "Georgia")
flag = NULL
peak = 30
years = c(2010, 2020)
remove1 = c("Bananas_ZZ_100s", "Apple_150-300_Pk", "Mango_mono")
remove2 = c("Tomato_ZR_400s", "cabbage300_Pk")

然后,我加载配置文件:

params = new.env()
source("config/config.R", params)
params = mget(ls(params), envir = params)

并获取带参数的命名列表:

> print(params)

$var1 
[1] "Fruit"

$var2 
[1] "Vegetables"

$country
[1] "BRAZIL"    "ECUADOR"    "Georgia" 

等等

我想将参数列表中的字符变量转换为小写,两个变量除外:remove1 和 remove2

我能够以这种方式转换列表中的所有个字符变量:

  params = lapply(params, function(params) {
  if (is.character(params)) return(tolower(params))
  else return(params)
  })

但我不知道如何将此函数(或者可能使用 for 循环)应用于所有字符 var。排除几个变量。

如果有任何帮助,我将不胜感激!

附: 我想得到什么:

> print(params)

$var1 
[1] "fruit"

$var2 
[1] "vegetables"

$country
[1] "brazil"  "ecuador"  "georgia" 

$flag
NULL

$peak
[1] 30

$years
[1] 2010   2020

$remove1
[1] "Bananas_ZZ_100s"   "Apple_150-300_Pk"   "Mango_mono"

$remove2
[1] "Tomato_ZR_400s"   "cabbage300_Pk"

【问题讨论】:

    标签: r list for-loop apply lapply


    【解决方案1】:

    由于您需要列表中的名称和值,我们可以使用Map

    Map(function(x, y) if(is.character(x) & !y %in% c('remove1', 'remove2'))
                       tolower(x) else x, params, names(params))
    
    
    #country
    #[1] "brazil"  "ecuador" "georgia"
    
    #$flag
    #NULL
    
    #$peak
    #[1] 30
    
    #$remove1
    #[1] "Bananas_ZZ_100s"  "Apple_150-300_Pk" "Mango_mono"      
    
    #$remove2
    #[1] "Tomato_ZR_400s" "cabbage300_Pk" 
    
    #$var1
    #[1] "fruit"
    
    #$var2
    #[1] "vegetables"
    
    #$years
    #[1] 2010 2020
    

    purrr::imap 可能更容易

    purrr::imap(params, ~if(is.character(.x) & !.y %in% c('remove1', 'remove2'))  
                         tolower(.x) else .x)
    

    您也可以先找出我们需要更改的元素,然后对它们应用tolower

    inds <- !names(params) %in% c('remove1', 'remove2') & sapply(params, is.character)
    params[inds] <- lapply(params[inds], tolower)
    

    【讨论】:

      【解决方案2】:

      如果有帮助,还有其他选择吗?

      params <- list(
        var1 = "Fruit",
        var2 = "Vegetables",
        country = c("BRAZIL", "ECUADOR", "Georgia"),
        flag = NULL,
        peak = 30,
        years = c(2010, 2020),
        remove1 = c("Bananas_ZZ_100s", "Apple_150-300_Pk", "Mango_mono"),
        remove2 = c("Tomato_ZR_400s", "cabbage300_Pk"))
      
      # list of params to exclude from tolower check
      exclude <- alist(remove1=, remove2=)
      
      # create an unnamed list with the correct params lowered
      params.lower <- lapply(names(params), function (name) {
      
        # if the name of the param is not in the exculsion list and the value is character
        if (!name %in% names(exclude) && is.character(params[[name]])) {
      
          # return the lower case value of the param
          tolower(params[[name]]) 
      
        } else { 
      
          # return the value of the param unchanged
          params[[name]]
        }
      })
      
      # assign the param names to the new list
      names(params.lower) <- names(params)
      
      params.lower
      #$var1
      #[1] "fruit"
      
      #$var2
      #[1] "vegetables"
      
      #$country
      #[1] "brazil"  "ecuador" "georgia"
      
      #$flag
      #NULL
      
      #$peak
      #[1] 30
      
      #$years
      #[1] 2010 2020
      
      #$remove1
      #[1] "Bananas_ZZ_100s"  "Apple_150-300_Pk" "Mango_mono"      
      
      #$remove2
      #[1] "Tomato_ZR_400s" "cabbage300_Pk" 
      
      

      【讨论】:

        猜你喜欢
        • 2021-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-13
        相关资源
        最近更新 更多