用于计算和打印的数据帧之间的循环

时间:2016-04-16 20:36:20

标签: r loops dataframe

我在使用for循环时遇到一些困难,我希望用它来链接来自2个不同数据帧的数据。 我将展示每个数据帧的一部分,但您需要知道这些数据帧的长度要大得多,因此我需要通过使用循环来解决我的问题。我无法放入图片,因为我是新手,所以我会尝试通过输入一小部分来说清楚:

数据框1:

Four columns: Treenr, X, Y and d    
first row: 1, 191.5, 240, 23.93    
second row: 2, 213.5, 153.5, 8.14

Dataframe 2

Three columns: Liananr, Xl, Yl     
first row: 1, 191.5, 240, 23.93    
second row: 2, 213.5, 153.5, 8.14

XY是坐标。 d是一段距离。 最终我想为每个藤本植物计算:r = sqrt((Xl-X)^2+(Yl-Y)^2)。我希望在一个新的数据框中,这给我4列:

Liananr, Treenr, r and d.

这应该给10行,因为每个liananr(5)链接到Treenr(2) 分别为每列提供以下行:

row 1: 1, 1, 91.11, 23.93    
row 2: 2, 1, 73.56, 29.93    
row 3: 3, 1, 73.56, 29.93    
row 4: 4, 1, 73.56, 29.93    
row 5: 5, 1, 55.22, 23.93    
row 6: 1, 2, 53.50, 8.14    
row 7: 2, 2, 58.22, 8.14    
row 8: 3, 2, 58.22, 8.14    
row 9: 4, 2, 58.22, 8.14    
row 10: 5, 2, 74.50, 8.14

我会将新数据框称为“已关联”。首先我定义:

X <- dataframe1$X    
Y <- dataframe1$Y    
Xl <- dataframe2$Xl    
Yl <- dataframe2$Yl   

for (i in 1:length(dataframe1$Treenr) {    
  for (j in 1:length(dataframe2$Liananr) {    
    Linked$Liananr <- dataframe2$Liananr    
    Linked$Treenr <- dataframe1$Treenr    
    Linked$r <- sqrt((Xl[j,]-X[i,])^2+(Yl[j,]-Y[i,])^2)    
    Linked$d <- dataframe1$d    
  }   
}

我最大的问题是我不知道如何在这个循环中使用i和j。

1 个答案:

答案 0 :(得分:1)

考虑使用交叉连接返回两个集合之间的所有组合配对(即cartesian product)。这避免了嵌套的for循环,因为计算可以按列处理。下面的示例将df1中的数字调整为两个帧的发布数据重复数据:

df1 <- data.frame(Treenr=c(1,2),
              X=c(181.5, 206.5),
              Y=c(230, 147.5),
              d=c(13.93, 1.14))
df1$key <- 1
df2 <- data.frame(Liananr=c(1,2),
                  X1=c(191.5, 213.5),
                  Y1=c(240, 153.5),
                  d=c(23.93, 8.14))
df2$key <- 1

crossdf <- merge(df1, df2, by='key')
crossdf
#   key Treenr     X     Y   d.x Liananr    X1    Y1   d.y
# 1   1      1 181.5 230.0 13.93       1 191.5 240.0 23.93
# 2   1      1 181.5 230.0 13.93       2 213.5 153.5  8.14
# 3   1      2 206.5 147.5  1.14       1 191.5 240.0 23.93
# 4   1      2 206.5 147.5  1.14       2 213.5 153.5  8.14
crossdf$r <- with(crossdf, sqrt((X1-X)^2+(Y1-Y)^2))

finaldf <- crossdf[c('Liananr', 'Treenr', 'r', 'd.y')]
names(finaldf)[4] <- 'd'
finaldf
#   Liananr Treenr         r     d
# 1       1      1 14.142136 23.93
# 2       2      1 82.923157  8.14
# 3       1      2 93.708324 23.93
# 4       2      2  9.219544  8.14