首页 > 解决方案 > R:for循环或应用于命名列表的某些元素

问题描述

例如,我有一个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。排除几个变量。

我将非常感谢任何帮助!

PS我想得到什么:

> 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"

标签: rlistfor-loopapplylapply

解决方案


由于您需要列表中的名称和值,我们可以使用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)

推荐阅读