2016-08-30 2 views
1

У меня есть data.frame с оценками в названных столбцах, мне нужно получить rowMeans определенных кластеров столбцов в соответствии с индексным файлом, который определяет, какие colNames необходимо сгруппировать. Я хотел бы сделать это одновременно, так как это выполняется в цикле, который проходит в текущем «кластере» для работы. Смотри ниже.Векторизовать эту петлю R и пользовательскую функцию

У меня есть два кадра данных, один индексный файл со следующим (плюс многое другое, это OBV только для примера)

set.seed(42) 
index <- data.frame(area=c("area1","area1","area1","area2","area2","area2","area1", 
    "area1","area4","area5"), name=c(paste0("name",sample(6,10,replace=T)))) 

Другой файл данных, снова здесь обедневший пример

data <- data.frame(name1=sample(10,5),name2=sample(10,5),name3=sample(10,5), 
     name4=sample(10,5),name5=sample(10,5),name6=sample(10,5)) 

Я сделал функцию, которая возвращает rowMeans для столбцов Д.Ф. «данные», которые составляют площадь в соответствии с «индексом» ф.р.

myfun <- function (curr.target) { 
     target.cols <- as.character(index$name[index$area==curr.target]) 
     return(rowMeans(data[target.cols],na.rm=T)) 
    } 

Затем я использую эту функцию, чтобы получить средства строк для областей, перейдя через области.

for (i in seq_along(unique(index$area))){ 
    data[,as.character(unique(index$area))[i]] <- myfun(as.character(unique(index$area))[i]) 
} 

Я избивая себя, пытаясь придумать, как сделать это в одной строке (после того, как функция написана), но просто не может положить палец на нем. Какие-либо предложения?

+0

Используйте 'set.seed', чтобы сделать это воспроизводимым как' sample'. – akrun

ответ

2

Мы можем split столбец «имя» в «индекс» на «области», то петли через list, подмножество «данными», основываясь на колонке «имя» в «индекс» и получить rowMeans

sapply(split(as.character(index$name), index$area), function(x) rowMeans(data[x])) 
+1

Спасибо, что @akrun, 'split' будет очень полезен, и я не сталкивался с этим раньше. Есть ли способ, которым я могу манипулировать именами столбцов вывода в этом вызове? В частности, переупорядочивание столбцов в соответствии с другим индексом и/или внесение имен в верхнем регистре с помощью 'toupper()'? – Alex

+0

@Alex Затем вам нужно «зациклиться» на последовательности «split» i.e. 'lst <- split (as.character (index $ name), index $ area); lapply (seq_along (lst), function (i) ...) 'Я не совсем уверен, что вы делаете. – akrun

2

Использование sapply() и cbind() так:

uia <- unique(index$area) 
cbind(data, sapply(uia, myfun)) 

результаты:

name1 name2 name3 name4 name5 name6 area1 area2 area4 area5 
1  5 10 10  6  8  9 8.2 6.666667  6  8 
2  7  9  2  4 10  1 5.6 6.000000  4 10 
3  8  1  8  8  4  2 3.4 6.666667  8  4 
4  2  4  7  9  5  7 5.0 7.666667  9  5 
5  3  7  1 10  1  4 3.8 7.000000 10  1 
Смежные вопросы