首页 > 解决方案 > 在 R 中创建一个包含重复单元格和计算的连续列

问题描述

我尝试使用以下数据集进行一些计算:

dataset <- data.frame(specimen = c("NIA","NIA","NIA","MAT","MAT"),
                      brakg = c(9.4,0,0,7.8,0),
                      cebkg = c(0,2.3,3.1,0,2.4),
                      rotkg = c(0,1,1.1,0,1.2),
                      stringsAsFactors = FALSE)

  specimen brakg cebkg rotkg
1      NIA   9.4   0.0   0.0
2      NIA   0.0   2.3   1.0
3      NIA   0.0   3.1   1.1
4      MAT   7.8   0.0   0.0
5      MAT   0.0   2.4   1.2

我想要brakg复制变量、变量cebkgrotkg可用以及从brakg - sum(cebkg)和计算brakg/sum(rotkg)。这应该是结果:

specimen    list    value
NIA         Init    9.4
NIA         Eval    9.4
NIA         Ceb     2.3
NIA         Ceb     3.1
NIA         Rot     1.0
NIA         Rot     1.1
NIA         DiffA   4.0
NIA         RateB   4.48
MAT         Init    7.8
MAT         Eval    7.8
MAT         Ceb     2.4
MAT         Rot     1.2
MAT         DiffA   5.4
MAT         RateB   6.5

我已经尝试过(没有成功)这段代码:

spds <- split(dataset, dataset$specimen)
# Splitting the dataset to make an evaluation per specimen

res <- lapply(spds, function(DF){
  i <- which(DF[['brakg']] != 0)
  j <- which(DF[['cebkg']] != 0)
  k <- which(DF[['rotkg']] != 0)
  tmp <- rbind(DF[rep(i, 2), ], DF[j, ], DF[k, ])
  # So I can stack the brakg value repetition... after that null ideas
})

请,任何帮助都是有用的,即使在基本 R 或 Tidyverse 中(我不知道 tidy 函数是否可以输出不同数量的变量)。谢谢你。

标签: rtidyverse

解决方案


This code is a little long, but I believe it is clear and easy to debug/edit.

DiffA = merge(
            dataset[which(dataset$brakg != 0), c(1, 2)],
            aggregate(cbind(cebkg = cebkg) ~ specimen, dataset[which(dataset$cebkg != 0), c(1, 3)], FUN="sum")
            )

RateB = merge(
            dataset[which(dataset$brakg != 0), c(1, 2)],
            aggregate(cbind(rotkg = rotkg) ~ specimen, dataset[which(dataset$rotkg != 0), c(1, 4)], FUN="sum")
            )

res = rbind(
        # Init
        with(dataset[which(dataset$brakg != 0), ], 
            data.frame(
                    speciment = specimen,
                    list = "Init",
                    val = brakg
                )
        ),
        # Eval
        with(dataset[which(dataset$brakg != 0), ], 
            data.frame(
                    speciment = specimen,
                    list = "Eval",
                    val = brakg
                )
        ),
        # RateB
        with(RateB, 
            data.frame(
                    speciment = specimen, 
                    list = "RateB",
                    val = brakg / rotkg
                )
        ),
        # DiffA
        with(DiffA, 
            data.frame(
                    speciment = specimen, 
                    list = "DifA", 
                    val = brakg - cebkg
                )
        ),
        # Ceb
        with(dataset[which(dataset$cebkg != 0), ], 
            data.frame(
                    speciment = specimen,
                    list = "Ceb",
                    val = cebkg
                )
        ),
        # Rot
        with(dataset[which(dataset$rotkg != 0), ],
            data.frame(
                    speciment = specimen,
                    list = "Rot",
                    val = rotkg
                )
        )
)


> res
   speciment  list     val
1        NIA  Init 9.40000
2        MAT  Init 7.80000
3        NIA  Eval 9.40000
4        MAT  Eval 7.80000
5        MAT RateB 6.50000
6        NIA RateB 4.47619
7        MAT  DifA 5.40000
8        NIA  DifA 4.00000
9        NIA   Ceb 2.30000
10       NIA   Ceb 3.10000
11       MAT   Ceb 2.40000
12       NIA   Rot 1.00000
13       NIA   Rot 1.10000
14       MAT   Rot 1.20000

推荐阅读