一般问题
我想更改在lapply / sapply(或mapply?)调用中传递给函数的其他参数。一般情况下,知道如何执行此操作将非常高兴。但是,如果有问题,出于我的特定目的,我正在尝试将其合并到自定义函数中。 (因此希望它可以扩展)。
问题的具体示例
假设我有以下数据框:
df <- data.frame(column1 = letters[1:4],
column2 = LETTERS[1:4],
column3 = 1:4,
stringsAsFactors = FALSE)
作为一个例子,我想将column1和column2转换为因子,每个因子具有不同的级别。我可能会注意到这样的列和级别:
# Columns in df I want to apply the factor() function to.
cols <- c("column1", "column2")
# Desired levels for column1
column1_lvl <- c(letters[1:5])
# Desired levels for column2
column2_lvl <- c(LETTERS[1:6])
请注意,我为列指定了两个单独的级别,每个级别都比df
中存在的级别更多。这是改变论点的动机。现在,我测试了lapply
调用,而没有将level参数的参数更改为factor:
df[cols] <- lapply(df[,cols], factor)
这可以成功地将那些列转换为因子。我将df
重新定义为下一步的原始结构。现在,我想为每个列指定级别。在?lapply
中,它表示您可以将其他参数传递给FUN
,但没有指定如何在X
中的每个向量上改变这些参数。尝试使用 one 实例,我可以这样写:
df["column1"]<- factor(df[,"column1"], levels = column1_lvl)
这有效。但是现在我想抽象levels
参数。不幸的是,这是行不通的,因为无论您为levels
分配了什么,R都会尝试将该参数用于X
中向量的 each 。
理想情况下,类似以下内容的方法将起作用。 以下是我希望可以按照我想要的方式工作的伪代码,但并非如此:
df[cols] <- lapply(df[,cols], factor, level = list(column1_lvl, column2_lvl))
我尝试过的事情
我无法找到许多资源来解释我如何能够做到这一点。也许,我不知道需要做什么。 This post对我有所帮助,但是我想知道是否有办法创建自己的factor
函数。
此外,this person's answer回答了他们自己的问题,促使我结识了mapply
。尽管我已经阅读了?mapply
的文档,并跟随了一些教程,但仍无法弄清楚。在那方面,我尝试了以下代码(出于我的目的)不起作用:
col_levels <- list(column1_lvl, column2_lvl)
df[cols] <- mapply(factor, df[,cols], MoreArgs = col_levels)
SessionInfo
> sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.5.1 tools_3.5.1 yaml_2.1.19
最终想法
我可能很难知道要搜索什么。如果您能够指出正确的方向,我总是愿意亲自解决问题。任何其他资源都值得欢迎。
先谢谢了!
答案 0 :(得分:3)
我们可以使用Map
来更改列levels
和list
中相应的'lvl'对象
df[cols] <- Map(function(x, y) factor(x, levels = y),
df[cols], list(column1_lvl, column2_lvl))
并检查列的levels
lapply(df[cols], levels)
#$column1
#[1] "a" "b" "c" "d" "e"
#$column2
#[1] "A" "B" "C" "D" "E" "F"
正如OP提到的使用lapply
解决此问题的方法一样,使用lapply
的一种选择是遍历序列,然后将数据和相应的“ lvls” list
子集化>
lvls_lst <- list(column1_lvl, column2_lvl)
df[cols] <- lapply(seq_along(lvls_lst), function(i)
factor(df[cols][[i]], levels = lvls_lst[[i]]))
注意:在这两种情况下,我们都需要明确指定levels