【问题标题】:For loop between dataframes with calculation and print用于计算和打印数据帧之间的循环
【发布时间】:2016-08-08 17:48:51
【问题描述】:

我在使用 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

数据框 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 行,因为对于每个链接到 Treenr (2) 的 liananr (5) 这分别为每一列提供了以下行:

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。

【问题讨论】:

    标签: r loops dataframe


    【解决方案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
    

    【讨论】:

    • 非常感谢,这让它变得容易多了!
    • 太棒了!如果回答有帮助,请接受以确认解决方案。
    猜你喜欢
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多