2016-08-09 4 views
1

я работаю большую матрицу (187682789 х 5)Изменить форму большой матрицы

Скажи это построить так:

Day1 <- rep(1, 10) 
Lat=sample(30:33, 10, replace=T) 
Lon=sample(-30:-33, 10, replace=T) 
Var=runif(10,1,100) 
Mat1<-cbind(Day1,Lat,Lon,Var) 


Day2 <- rep(2, 10) 
Lat=sample(30:33, 10, replace=T) 
Lon=sample(-30:-33, 10, replace=T) 
Var=runif(10,1,100) 
Mat2<-cbind(Day2,Lat,Lon,Var) 

#... And so on, but let's stick to 2 days for the example 

Mat = rbind(Mat1,Mat2) 

Конечно здесь есть избыточность числа уникального комбината Лат Лон.

position=cbind(Mat[,2],Mat[,3]) # Lat Lon 
nrow(unique(position)) < nrow(position) #True 

Я хотел бы получить матрицу, которая показывает весь уникального Lat Lon combinaison следует все соответствующему переменному в день.

Например:

> Mat 
      Day Lat Lon  Var 
    [1,] 1 36 -36 51.086210 
    [2,] 1 37 -37 48.486008 
    [3,] 1 38 -38 39.482635 
    [4,] 1 39 -39 97.848232 
    [5,] 1 40 -40 71.076543 
    [6,] 2 31 -31 5.641855 
    [7,] 2 32 -32 62.124584 
    [8,] 2 33 -33 39.524119 
    [9,] 2 34 -34 7.214646 
    [10,] 2 35 -35 94.254170 
    [11,] 2 36 -36 40.615783 
    [12,] 2 37 -37 71.319719 
    [13,] 2 38 -38 81.775119 
    [14,] 2 39 -39 49.224411 
    [15,] 2 40 -40 80.813237 

стал бы:

>Resulting.Mat.Var 
    Unique.Lat Unique.Lon Day1   Day2 
    [1,] 36 -36  51.08621 40.615783 
    [2,] 37 -37  48.48601 71.319719 
    [3,] 38 -38  39.48264 81.775119 
    [4,] 39 -39  97.84823 49.224411 
    [5,] 40 -40  71.07654 80.813237 
    [6,] 31 -31   NA 5.641855 
    [7,] 32 -32   NA 62.124584 
    [8,] 33 -33   NA 39.524119 
    [9,] 34 -34   NA 7.214646 
    [10,] 35 -35   NA 94.254170 

Я попытался создать Матрицу НСБУ и залейте его 2 для петель, но это на самом деле занимает слишком много времени!

Большое спасибо!

Edit: Это несколько отличается от того, что я нашел на SO, так как это действительно нужно эффективности, все в цифровом формате, и есть 2 колонки, которые формируют позицию ...

J

+1

Возможный дубликат [Изменить данные из длинного в широкий формат R] (http://stackoverflow.com/questions/5890584/reshape-data-from-long-to-wide-format-r) – dww

ответ

2

В этом представляет собой типичную проблему преобразования «в длину». Одним из возможных вариантов для получения желаемой формы является использование dcast() из reshape2 пакета:

library(reshape2) 
as.matrix(dcast(as.data.frame(Mat), Lat + Lon ~ Day, value.var = "Var")) 
#  Lat Lon  1   2 
# [1,] 31 -31  NA 5.641855 
# [2,] 32 -32  NA 62.124584 
# [3,] 33 -33  NA 39.524119 
# [4,] 34 -34  NA 7.214646 
# [5,] 35 -35  NA 94.254170 
# [6,] 36 -36 51.08621 40.615783 
# [7,] 37 -37 48.48601 71.319719 
# [8,] 38 -38 39.48264 81.775119 
# [9,] 39 -39 97.84823 49.224411 
#[10,] 40 -40 71.07654 80.813237 

Довольно много подобных вопросов был дан ответ, прежде чем на SO, так что это, вероятно, дубликат. Однако большинство вопросов относятся к структурам data.frame, а не к матрицам.

данные:

Mat <- structure(c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 
      37, 38, 39, 40, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -36, 
      -37, -38, -39, -40, -31, -32, -33, -34, -35, -36, -37, -38, -39, 
      -40, 51.08621, 48.486008, 39.482635, 97.848232, 71.076543, 5.641855, 
      62.124584, 39.524119, 7.214646, 94.25417, 40.615783, 71.319719, 
      81.775119, 49.224411, 80.813237), .Dim = c(15L, 4L), 
      .Dimnames = list(NULL, c("Day", "Lat", "Lon", "Var"))) 
+0

Работал отлично, хотя у меня было чтобы разбить исходную матрицу на несколько более мелких, но я объединил их назад и получил тот же результат, поэтому спасибо! –

+0

@JLal Расщепление матрицы звучит несколько опасно. Я предполагаю, что это было необходимо из-за пределов RAM. Вероятно, вам нужно было убедиться, что после раскола данные, принадлежащие одному дню, не были распределены на разных матрицах. Во всяком случае, я рад слышать, что это сработало. – RHertel

+0

@JLal Пожалуйста, рассмотрите [принятие одного из ответов] (http://meta.stackexchange.com/q/5234), если это поможет решить вашу проблему. – RHertel

1

Другой метод, использующий dplyr является:

library(dplyr) 
Resulting.Mat.Var <- as.matrix(
    Mat %>% group_by(Unique.Lat=Lat,Unique.Lon=Lon) %>% 
      summarise(Day1=Var[which(Day==1)], Day2=Var[which(Day==2)])) 

print(Resulting.Mat.Var) 
##  Unique.Lat Unique.Lon  Day1  Day2 
## [1,]   31  -31  NA 5.641855 
## [2,]   32  -32  NA 62.124584 
## [3,]   33  -33  NA 39.524119 
## [4,]   34  -34  NA 7.214646 
## [5,]   35  -35  NA 94.254170 
## [6,]   36  -36 51.08621 40.615783 
## [7,]   37  -37 48.48601 71.319719 
## [8,]   38  -38 39.48264 81.775119 
## [9,]   39  -39 97.84823 49.224411 
##[10,]   40  -40 71.07654 80.813237 
+0

Ммм, но что, если у вас много разных (и почти бесчисленных) дней?Кроме того, я не настолько комфортно с dplyr lib, и такие операторы%>% незнакомы, но я обязательно буду в этом разбираться. Благодаря ! –

1

Похоже слияния мне:

> merge(Mat[Mat[,'Day']==1 , -1], Mat[ Mat[,'Day']==2, -1], by=c(1,2) , all=TRUE) 
    Lat Lon Var.x  Var.y 
1 31 -31  NA 5.641855 
2 32 -32  NA 62.124584 
3 33 -33  NA 39.524119 
4 34 -34  NA 7.214646 
5 35 -35  NA 94.254170 
6 36 -36 51.08621 40.615783 
7 37 -37 48.48601 71.319719 
8 38 -38 39.48264 81.775119 
9 39 -39 97.84823 49.224411 
10 40 -40 71.07654 80.813237 

Может принудить к матричным, если это необходимо, так что результатом является data.frame

+0

Мне это нравится. Но я думаю, что ОП указал, что исходные данные содержат более двух дней. – RHertel

+0

Тогда подумал бы о вызове 'Reduce' для' merge'. –

+0

Да, поскольку RHertel упоминал, что это нужно делать несколько дней, но я буду иметь в виду инструмент «слияния», по крайней мере, для контекста, когда я определяю свою проблему. Спасибо ! –

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