按列扩展矩阵

时间:2015-04-18 11:30:30

标签: r expand

我无法将数据集扩展为每个变量的所有组合。我们有一个数据集,其中包含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的变体可以实现此目的,我可能必须创建基于Npointsiterate的函数才能扩展此功能或者取决于点数和迭代次数,但是在这个阶段对我来说这有点复杂,似乎有很多低效的方法可以实现这一点。

非常感谢提前。

2 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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