2016-08-10 2 views
-4

Здравствуйте, я пытаюсь написать функцию, которая будет принимать фрейм данных, и исправить его соответствующие заголовки столбцов, если в имени есть специальный символ или пробел. Функция, похоже, работает, поскольку результаты печатаются, но, похоже, не сохраняют соответствующие изменения в исходном фрейме. Мысли о том, как это исправить? Данные, которые я использовал для тестирования, были tbl_df, поэтому я не уверен, что это связано с тем, почему он не обновляется правильно. Благодарю.Функция не сохраняет изменения в DataFrame

nameChange <- function(df) { 
    for(i in 1:length(colnames(df)[i])) { 
    if(str_detect(colnames(df[i]),"[:punct:]|[:space:]") == TRUE) { 
    #Could use "\\s" to find space 
    names(df) <- str_replace_all(names(df)," *",'') 
    names(df) <- str_replace_all(names(df),"-",'') 
    #df <- df 
    assign('df',df, envir=.GlobalEnv) 
    #return(df) 
    print("Worked") 
    } 

    else{ 
     print("Function did not replace anything") 
    } 
    } 
} 

Это данные, я использую для тестирования функции:

#data from: http://www.tableau.com/learn/tutorials/on-demand/getting-started-data 
orders_path <- file.path("/Users/petergensler/Desktop/Global Superstore.xls") 
order_table <- read_excel(orders_path, sheet = "Orders") 
nameChange(order_table) 

После того, как я называю COLNAMES на order_table вы должны быть в состоянии видеть, что дефис в продукте Подкатегорий удаляется, и все пробелы внутри каждого имени столбца больше не существуют.

+0

Просто проверить ... 'str_replace_all (имена (df)," * ", '')' и 'str_replace_all (имена (df)," - ", '')' дают желаемый результат? –

+0

Да, я знаю, что часть функции работает правильно. Я мог бы использовать \\ s для поиска пробелов в строках или [: space:] для их обнаружения. Моя реальная проблема заключается в том, что когда я передаю это tbl_df, он показывает внесенные изменения, но когда я вызываю colnames на tbl_df, это не похоже, что изменения были сохранены. – petergensler

+0

Он говорит, что это сработало, но по-прежнему не похоже, что он сохраняет результаты. – petergensler

ответ

4

Ваша функция может быть упрощено:

nameChange <- function(df) { 
    names(df) <- str_replace_all(names(df), "[:punct:]|[:space:]", "") 
    return(df) 
} 

Пример:

library(dplyr) 
library(stringr) 

df <- tbl_df(mtcars) 
names(df)[1] <- "m p g" 
names(df)[2] <- "c-y-l" 
names(df) 
# [1] "m p g" "c-y-l" "disp" "hp" "drat" "wt" "qsec" "vs" "am" 
# [10] "gear" "carb" 

df <- nameChange(df) 
names(df) 
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear" 
# [11] "carb" 
+0

Это не то, что я пытаюсь сделать вообще. Я хочу определить функцию, которая принимает в кадре данных, ищет символы на основе [: punct:] | [: space:] = и сохраняет результаты в кадре данных, который я ему предоставил. – petergensler

+1

Пример выше делает именно то, что вы просили. df - это предоставленный фрейм данных. Функция str_replace_all ищет узорную строку (замените ее здесь). а затем возвращает df и сохраняет результаты в исходный фрейм данных. – Dave2e

0

Любые другие вопросы в сторону (упоминается в комментарии, а i в цикле for не определено), то вопрос, как представляется, что вы не назначаете обратно исходный объект данных:

assign('df',df, envir=.GlobalEnv) 

присваивает объекту df, который, как я полагаю, вы найдете в своей среде после успешного запуска функции.

Предположительно вы хотите

dfname <- deparse(substitute(df)) 
assign(dfname, df, envir=.GlobalEnv) 

, который, кажется, работает на тестировании.

+0

i должно быть общее количество столбцов в кадре данных (что равно 24). Длина (COLNAMES (order_table) []). поэтому для каждого элемента, начинающегося с 1 по 24, когда оператор IF равен TRUE, он запускается. поэтому он должен увеличиваться каждый раз, когда он запускается. – petergensler

+0

@petergensler у вас есть 'for (i in 1: length (colnames (df) [i]))' в вашем вопросе; что второй 'i' не определен. В любом случае, что не так с '1: ncol (df)' или еще лучше 'seq_along (df)'? –

+0

Извините, я думаю, что я опубликовал плохую версию моего кода .... если вы пишете colnames (супермаркет [1]), он возвращает «Row ID», который является первым именем столбца в наборе данных – petergensler

-2

Ниже приведен код, который отвечает на мою проблему:

test1 <- function(df){ 
    names(df) <- str_replace_all(names(df), "[:punct:]|[:space:]","") 
    df <<- df 
    return(df) 
} 

Там нет ничего плохого в использовании ФРА в качестве аргумента, но вы потребности использовать глобальное назначение < < - оператор, так что эта функция можно вызвать практически на любом фрейме данных и перезаписать существующий df в рабочей области. Спасибо за вашу помощь.

+1

Да, я буду рад видеть, как эти ниспадающие вещи накапливаются. Хотя я рад за то, что вы нашли что-то, что работает, это не отвечает на ваш вопрос: «Что не так с этим?» '<< -' эквивалентен моему ответу, а не откровению для тех, кто вам ответил. В любом случае это считается очень плохой практикой. Возврат 'df' и назначение - стандартный подход R. –

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