Различные аргументы переданы функции в вызове lapply - PullRequest
0 голосов
/ 25 сентября 2018

Общая проблема

Я хочу изменить дополнительные аргументы, передаваемые функции при вызове 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 вызов без , не меняя аргумент уровней на фактор:

     df[cols] <- lapply(df[,cols], factor)

Это работает и успешно преобразует эти столбцы в факторы.Я переопределил df к его первоначальной структуре для следующего шага.Теперь я хочу указать уровни для каждого из столбцов.В ?lapply говорится, что вы можете передавать дополнительные аргументы в FUN, но не указывается, как изменять эти аргументы для каждого вектора в X.Пытаясь это с one instance, я могу написать это:

     df["column1"]<- factor(df[,"column1"], levels = column1_lvl)

Это работает.Но теперь я хочу абстрагироваться от аргумента levels.К сожалению, это не работает, потому что независимо от того, что вы присваиваете levels, R будет пытаться использовать этот аргумент для каждого векторов в X.

В идеале,что-то вроде следующего будет работать. Ниже приведен фальшивый код, который, как мне хотелось бы, работал бы так, как я хочу, но не :

     df[cols] <- lapply(df[,cols], factor, level = list(column1_lvl, column2_lvl))

То, что я пробовал

Мне не удалось найти много ресурсов, объясняющих, как я мог бы достичь этого.Или, может быть, я не вижу, что нужно сделать. Этот пост мне немного помог, но мне интересно, есть ли способ, например, создать мою собственную функцию factor.

Дополнительно, ответ этого человека на свой вопрос побудил меня проверить 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  

Заключительные мысли

Мне может быть трудно узнать, что искать.Я всегда открыт для выяснения проблемы сам, если вы можете указать мне правильное направление.Любые дополнительные ресурсы приветствуются.

Заранее спасибо!

1 Ответ

0 голосов
/ 25 сентября 2018

Мы можем использовать Map, чтобы изменить столбец levels с соответствующими объектами 'lvl' в list

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"

Поскольку ОП упомянул способ решения этой проблемы с помощью 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...