2015-04-18 2 views
1

У меня возникли проблемы с расширением набора данных во все комбинации каждой переменной. У нас есть набор данных с номером Npoints столбцов, каждый из которых состоит из числа iterate X, Y указывает себя. Данные выглядят как это, когда Npoints является 3 и iterate является 4.Развернуть матрицу по столбцам

X1 Y1 X2 Y2 X3 Y3 
20 1  30 1.5 50 0.9 
21 1.1 33 1.3 45 1 
19 0.9 28 1.6 53 1 
25 1.2 31 1.4 55 1.2 

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

foo <= function(x1, y1, x2, y2) { 
       y2 - x2*(y2 - y1)/(x2 - x1) 
} 

Получившийся файл должен выглядеть следующим образом

x1 y1 x2 y2 
20 1  30 1.5 
21 1.1 33 1.3 
19 0.9 28 1.6 
25 1.2 31 1.4 
20 1  50 0.9 
21 1.1 45 1 
19 0.9 53 1 
25 1.2 55 1.2 
30 1.5 50 0.9 
33 1.3 45 1 
28 1.6 53 1 
31 1.4 55 1.2 

Там, кажется, не быть разновидностью expand.grid, что может это сделать, и мне, возможно, придется создать функцию, основанную на Npoints и iterate, чтобы масштабировать ее вверх или вниз в зависимости от количества точек и итераций, однако это немного сложно для меня на данном этапе, и кажется, что есть многие неэффективные способы достижения этого.

Большое спасибо за внимание.

ответ

2
#split the df into Npoints data frames 
Npoints <- 3 
l <- lapply(1:Npoints, function(i)df[,(2*i-1):(2*i)]) 
#cbind the data frames for each possible combination of Npoints 
l1 <- apply(combn(Npoints, 2), 2, function(x)cbind(l[[x[1]]], l[[x[2]]])) 
#rbind all 
data.table::rbindlist(l1) 
# X1 Y1 X2 Y2 
# 1: 20 1.0 30 1.5 
# 2: 21 1.1 33 1.3 
# 3: 19 0.9 28 1.6 
# 4: 25 1.2 31 1.4 
# 5: 20 1.0 50 0.9 
# 6: 21 1.1 45 1.0 
# 7: 19 0.9 53 1.0 
# 8: 25 1.2 55 1.2 
# 9: 30 1.5 50 0.9 
#10: 33 1.3 45 1.0 
#11: 28 1.6 53 1.0 
#12: 31 1.4 55 1.2 

данные

structure(list(X1 = c(20L, 21L, 19L, 25L), Y1 = c(1, 1.1, 0.9, 
1.2), X2 = c(30L, 33L, 28L, 31L), Y2 = c(1.5, 1.3, 1.6, 1.4), 
    X3 = c(50L, 45L, 53L, 55L), Y3 = c(0.9, 1, 1, 1.2)), .Names = c("X1", 
"Y1", "X2", "Y2", "X3", "Y3"), class = "data.frame", row.names = c(NA, 
-4L)) 
0

Там может быть проще, но это дает вам решение:

данных

df <- data.frame(X1=c(20, 21, 19, 25), 
      Y1=c(1, 1.1, 0.9, 1.2), 
      X2=c(30, 33, 28, 31), 
      Y2=c(1.5, 1.3, 1.6, 1.4), 
      X3=c(50, 45, 53, 55), 
      Y3=c(0.9, 1, 1, 1.2) 
) 

Код

# Define how many pairs of columns you have 
Npoints <- 3 

# Get all different combinations 
cmb <- combn(1:Npoints, 2) 
cmb <- rbind(cmb, cmb) 
cmb <- apply(cmb, 2, sort) 

# Create combination of column names 
cmb <- apply(cmb, 2, function(z) paste0(c("X", "Y"), z)) 

# Create list of data frames based on the column combinations 
df <- apply(cmb, 2, function(z) df[, z]) 

# Change the column names of each data frame in list, becaise we are going to append them 
for(i in 2:length(df)){ 
    names(df[[i]]) <- names(df[[1]]) 
} 

# Append the data frames of the list 
df <- do.call(rbind, df) 

Результат

df 

# x1 y1 x2 y2 
# 20 1  30 1.5 
# 21 1.1 33 1.3 
# 19 0.9 28 1.6 
# 25 1.2 31 1.4 
# 20 1  50 0.9 
# 21 1.1 45 1 
# 19 0.9 53 1 
# 25 1.2 55 1.2 
# 30 1.5 50 0.9 
# 33 1.3 45 1 
# 28 1.6 53 1 
# 31 1.4 55 1.2 
Смежные вопросы