2015-06-29 3 views
0

Во-первых, вот мой код:Добавляя значения к вектору в функции

count <- vector() 
f1 <- function(x) { 
    file <- read.csv(x) 
    date <- grep(pattern = "lalala", names(file)) 
    file <- file[date] 

    file.row <- unlist(file) 
    num <- length(unique(file.row)) 
    count <- c(count, num) 
} 

files <- list.files(path="path/to/directory", pattern="*.csv", full.names=TRUE) 
lapply(files, f1) 

Я пытаюсь сохранить целое, Num, в счетный вектор. Однако вызов этого скрипта дает мне пустой вектор счета, поэтому я тестировал, чтобы узнать, какое значение счетчика было при каждом запуске функции, и оно печатает правильные значения, за исключением того, что вектор count повторно инициализирует пустой вектор в начале каждого запуска функции. Что происходит и как я могу это исправить?

+1

Проблема в том, что вашей функции требуется возвращаемое значение. Кстати, динамически растущие вещи - плохая идея. – Frank

+1

«вектор счета переинициализируется на пустой вектор в начале каждого запуска функции» - так работают функции на языках функционального программирования (например, R). – Gregor

+0

R ведет себя так, как должно, читайте в [лексическом масштабе] (http://adv-r.had.co.nz/Functions.html#lexical-scopingl) – jeremycg

ответ

1

Не проверено, но право Фрэнка должно быть равно return() вашего счета, и пусть функция apply делает добавление. Я переключился на sapply, так что вы должны получить вектор назад вместо списка:

f1 <- function(x) { 
    file <- read.csv(x) 
    date <- grep(pattern = "lalala", names(file)) 
    file <- file[date] 

    file.row <- unlist(file) 
    return(length(unique(file.row))) 
} 

files <- list.files(path="path/to/directory", pattern="*.csv", full.names=TRUE) 
count = sapply(files, f1) 
+0

Это сработало, но когда я просто набираю счет, чтобы увидеть значения внутри вектора, весь путь и индекс печатаются в одной строке. Я, вероятно, не сделал этого достаточно ясно, поэтому приведу пример: C:/путь/имя C:/path/name2 2 ..... и так далее. – user3755880

+0

Результатом является именованный вектор. Если вы не хотите, чтобы имена просто «igname()» результат. – Gregor

2

Если я вас правильно понимаю, что вы хотите просто

f1 <- function(x) { 
    file <- read.csv(x) 
    date <- grep(pattern = "lalala", names(file)) 
    file <- file[date] 

    file.row <- unlist(file) 
    num <- length(unique(file.row)) 
    num ## implicitly return `num` 
} 

files <- list.files(path="path/to/directory", pattern="*.csv", full.names=TRUE) 
lapply(files, f1) 

ПримечаниеЭтот (lapply()) будет возвращать список так что вы можете упростить его, используя вместо sapply():

sapply(files, f1) 

Примечание вам не нужно вызывать return() явно в f1(), поскольку это уже сделано для вас.

+0

@plafort Да, хотя я часто нахожу, что это помогает мне взглянуть на код, чтобы увидеть возвращаемый объект, поскольку я даю ему имя, которое для меня что-то значит. Я знаю, что придется разбирать 'length (unique (file.row))' каждый раз, когда я читаю код, но помещая что-то вроде 'nvars' или что-то в равной степени информативное, я бы знал, на что я собираюсь вернуться. (Должен признаться, что не прочитал и полностью не понял, что здесь делает код OP - я просто использовал 'num' как возвращаемый объект. –

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