2015-11-02 6 views
2

Я пытаюсь реплицировать решение при применении нескольких функций в sapply, размещенном на R-Bloggers, но я не могу заставить его работать желаемым образом. Я работаю с простым набором данных, похожий на тот, генерироваться ниже:Применение нескольких функций через sapply

require(datasets) 
crs_mat <- cor(mtcars) 

# Triangle function 
get_upper_tri <- function(cormat){ 
    cormat[lower.tri(cormat)] <- NA 
    return(cormat) 
} 

require(reshape2) 
crs_mat <- melt(get_upper_tri(crs_mat)) 

Я хотел бы заменить некоторые текстовые значения по столбцам Var1 и VAR2. ошибочными синтаксис ниже иллюстрирует то, что я пытаюсь достичь:

crs_mat[,1:2] <- sapply(crs_mat[,1:2], function(x) { 
# Replace first phrase 
gsub("mpg","MPG",x), 
# Replace second phrase 
    gsub("gear", "GeArr",x) 
# Ideally, perform other changes 
}) 

Естественно, что код не является синтаксически правильным и не удается. Подводя итог, я хотел бы сделать следующее:

  1. Пройдите через все значения в первых двух столбцах (Var1 и var2) и выполнять простые замены через gsub.
  2. В идеале я хотел бы избежать определения отдельной функции, как описано в linked пост и держать все в синтаксис sapply
  3. Я не хочу, вложенный цикл

Я рассмотрел широко подобный предмет, обсуждаемый here и here, но, если возможно, я хотел бы избежать использования plyr. Я также заинтересован в замене значений столбцов не на создание новых столбцов, и я хотел бы избежать указания имен столбцов. Во время работы с существующим фреймом данных мне удобнее использовать номера столбцов.

Редактировать

После очень полезные замечания, что я пытаюсь достичь можно резюмировать ниже решения:

fun.clean.columns <- function(x, str_width = 15) { 
    # Make character 
    x <- as.character(x) 
    # Replace various phrases 
    x <- gsub("perc85","something else", x) 
    x <- gsub("again", x) 
    x <- gsub("more","even more", x) 
    x <- gsub("abc","ohmg", x) 
    # Clean spaces 
    x <- trimws(x) 
    # Wrap strings 
    x <- str_wrap(x, width = str_width) 
    # Return object 
    return(x) 
} 
mean_data[,1:2] <- sapply(mean_data[,1:2], fun.clean.columns) 

не нужна эта функция в моем global.env, так что я могу работать rm после этого, но даже более приятное решение будет включать в себя сжать это в рамках синтаксиса apply.

+0

Можете ли вы подробнее рассказать о других изменениях, которые вы хотите сделать? Сколько у вас есть замены? – Heroka

+0

@Heroka, спасибо за проявление интереса. Предположим, что я готов сделать 10 замен и других косметических изменений, например, «trimws».В принципе, 'gsub' для меня достаточно, но я хочу иметь возможность применять различные итерации команд' gsub' к столбцам, которые я решаю передать через 'sapply'. – Konrad

+0

Основная проблема, с которой вы столкнулись, заключается в том, что вы ничего не назначаете, поэтому никаких изменений не производится. – Heroka

ответ

3

Мы можем использовать mgsub из library(qdap) для замены нескольких шаблонов. Здесь я зацикливаю первый и второй столбцы с помощью lapply и присваиваю результаты обратно crs_mat[,1:2]. Обратите внимание, что я использую lapply вместо sapply в lapply сохраняет структуру нетронутыми

library(qdap) 
crs_mat[,1:2] <- lapply(crs_mat[,1:2], mgsub, 
    pattern=c('mpg', 'gear'), replacement=c('MPG', 'GeArr')) 
+0

Большое спасибо за ваш вклад. Решение, безусловно, будет работать в случае 'gsub', меня больше всего интересует расширение синтаксиса' sapply', так как я хотел бы воспользоваться доступной гибкостью. Например, мне, возможно, придется применять 'gsub' 5 раз, после' trimws' и, наконец, 'toupper' или что-то на этих строках. – Konrad

+1

@ Konrad Я думаю, вы посмотрели пример, показанный на рисунке 'lapply' vs' sapply' – akrun

+0

Я это сделал, но мне непонятно, можно ли создать синтаксис dequate. Я понимаю, что могу определите новую функцию 'my_problematic_strings <- function (string_var) {# Все, что я хочу сделать}', а затем передадим ее: 'sapply (dta_with_columns, function (x) my_problematic_strings)'. В идеале я бы не хотел определять эта функция, поскольку она будет "сидеть" в глобальной среде без каких-либо причин. – Konrad

3

Здесь вы найдете решение для вас, я думаю, вы сможете его расширить. Есть, вероятно, более элегантные подходы, но я не вижу их атм.

crs_mat[,1:2] <- sapply(crs_mat[,1:2], function(x) { 
    # Replace first phrase 
    step1 <- gsub("mpg","MPG",x) 
    # Replace second phrase. Note that this operates on a modified dataframe. 
    step2 <- gsub("gear", "GeArr",step1) 
    # Ideally, perform other changes 
    return(step2) 

    #or one nested line, not practical if more needs to be done 
    #return(gsub("gear", "GeArr",gsub("mpg","MPG",x))) 
}) 
+0

Спасибо, это начало. – Konrad

Смежные вопросы