R根据公式匹配数据框中的行

时间:2016-10-13 12:56:35

标签: r dataframe

我有一个包含7列的数据框,我想添加一个包含“父行”信息的列。这听起来很模糊,所以我将用一个例子来澄清。您可以在下面看到数据框:

 `        Nclass0        Nclass1 BestSBestI impurity n
[1,]       5       5     4  36.0 0.2500000 10
[2,]       5       2     1  37.0 0.2040816  7
[3,]       4       0    -1  -1.0 0.0000000  4
[4,]       1       2     2   0.5 0.2222222  3
[5,]       1       0    -1  -1.0 0.0000000  1
[6,]       0       2    -1  -1.0 0.0000000  2
[7,]       0       3    -1  -1.0 0.0000000  3`     

使用nclass0和nclass1,我想添加第8列,其中匹配对具有相同的id。第一行是父行(id = 0)。如果[rowX,1] + [rowY,1]等于父行nclass0并且[rowX,2] + [rowY,2]等于父行nclass1,则行匹配。 RowX和rowY是子行,应该得到id = 1。

在这种情况下,父行[1,]具有子行[2,]& [7,],这些行应该得到id = 1。在此之后,第二行成为具有自己的子行[3,]和[4,]并且id = 2的父行,直到所有具有子行的行都被赋予了id。

我做了几次尝试,但失败了。有没有人建议如何做到这一点?这种情况的理想输出是:

`    Nclass0       Nclass1  BestS BestI impurity n id
[1,]       5       5     4  36.0 0.2500000 10  0
[2,]       5       2     1  37.0 0.2040816  7  1
[3,]       4       0    -1  -1.0 0.0000000  4  2
[4,]       1       2     2   0.5 0.2222222  3  2
[5,]       1       0    -1  -1.0 0.0000000  1  4
[6,]       0       2    -1  -1.0 0.0000000  2  4
[7,]       0       3    -1  -1.0 0.0000000  3  1` 

1 个答案:

答案 0 :(得分:0)

这是一个使用SELECT platform, country, Source, window, Round(SUM(ProjectedARPI*PlayerCount) / SUM(PlayerCount), 2) AS ProjectedARPI, Round(SUM(ProjectedARPIOrganicLow*PlayerCount) / SUM(PlayerCount), 2) AS ProjectedARPIOrganicLow, Round(SUM(ProjectedARPIOrganicMed*PlayerCount) / SUM(PlayerCount), 2) AS ProjectedARPIOrganicMed, Round(SUM(ProjectedARPIOrganicHigh*PlayerCount) / SUM(PlayerCount), 2) AS ProjectedARPIOrganicHigh, SUM(PlayerCount) AS PlayerCount, SUM(PayerCount) AS PayerCount, CASE WHEN(SUM(PlayerCount) > 500 AND SUM(PayerCount) > 10) THEN TRUE ELSE FALSE END AS isSignificant, ProjectionDate, min(CohortRangeLow) as CohortRangeLow, max(CohortRangeHigh) as CohortRangeHigh FROM web_synch.UI_data WHERE PlayerCount > 0 AND ProjectionDate BETWEEN '2015-07-25' AND '2016-10-25' AND window = 365 GROUP BY Platform, country, source, ProjectionDate ORDER BY Platform, source, ProjectionDate; 循环的解决方案。循环将一直运行,直到每一行都有while值,或者直到它已经评估了数据框中的所有行。我确信有一些弱点,但这是一个好的开始:

注意:我认为这在大型数据框架中会变得无法忍受,所以我希望你不需要在任何大的数据框架上执行此操作(每个id需要大约1秒才能在10,000的向量上完成)。

outer

解释

要尝试澄清您的问题,您正在寻找DF <- structure(list(Nclass0 = c(5, 5, 4, 1, 1, 0, 0), Nclass1 = c(5, 2, 0, 2, 0, 2, 3), BestS = c(4, 1, -1, 2, -1, -1, -1), BestI = c(36, 37, -1, 0.5, -1, -1, -1), impurity = c(0.25, 0.2040816, 0, 0.2222222, 0, 0, 0), n = c(10, 7, 4, 3, 1, 2, 3)), .Names = c("Nclass0", "Nclass1", "BestS", "BestI", "impurity", "n"), row.names = c(NA, -7L), class = "data.frame") DF[["id"]] <- c(0, rep(NA, nrow(DF) - 1)) i <- 1 while(sum(is.na(DF[["id"]])) > 0){ cross0 <- outer(DF[["Nclass0"]], DF[["Nclass0"]], `+`) match0 <- cross0 == DF[["Nclass0"]][i] & lower.tri(cross0) cross1 <- outer(DF[["Nclass1"]], DF[["Nclass1"]], `+`) match1 <- cross1 == DF[["Nclass1"]][i] & lower.tri(cross1) rows <- as.vector(which(match0 & match1, arr.ind = TRUE)) if (length(rows)) DF[["id"]][rows] <- i if (i == nrow(DF)) break else i <- i + 1 } x1 + x2 = x_ref的对。

这段代码的作用是制作一个矢量与自身的所有可能成对和的矩阵。这是通过y1 + y2 = y_ref完成的。

outer

当试图找到第一行的x匹配时,我们将此矩阵与outer(DF[["Nclass0"]], DF[["Nclass0"]], `+`) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [1,] 10 10 9 6 6 5 5 [2,] 10 10 9 6 6 5 5 [3,] 9 9 8 5 5 4 4 [4,] 6 6 5 2 2 1 1 [5,] 6 6 5 2 2 1 1 [6,] 5 5 4 1 1 0 0 [7,] 5 5 4 1 1 0 0 进行比较(并将上三角设置为false以避免重复)。

DF$class0[1]

我们对match0 <- cross0 == DF[["Nclass0"]][1] & lower.tri(cross0) match0 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [3,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [4,] FALSE FALSE TRUE FALSE FALSE FALSE FALSE [5,] FALSE FALSE TRUE FALSE FALSE FALSE FALSE [6,] TRUE TRUE FALSE FALSE FALSE FALSE FALSE [7,] TRUE TRUE FALSE FALSE FALSE FALSE FALSE

重复此过程
Nclass1

要查找行索引,我们希望找到这两个cross1 <- outer(DF[["Nclass1"]], DF[["Nclass1"]], `+`) match1 <- cross1 == DF[["Nclass1"]][1] & lower.tri(cross1) match1 [,1] [,2] [,3] [,4] [,5] [,6] [,7] [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [3,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE [4,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [5,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE [7,] FALSE TRUE FALSE TRUE FALSE TRUE FALSE 矩阵的交集 - 换句话说,两个矩阵中的match个位置都是which

TRUE

因此第7行和第2行与第一行相关。我们可以为每个后续行重复此操作,直到我们为每一行分配了一个ID。

将其转换为函数

这是一个函数,它接受一个数据框,一个x-match的列名,一个y-match的列名,以及一个用来命名id变量的字符。我添加了一些铃声和口哨来检查输入。

as.vector(which(match0 & match1, arr.ind = TRUE))
[1] 7 2