R:创建2列,其中包含另一列的差异和百分比值

时间:2015-06-18 21:41:41

标签: r dataframe data.table plyr dplyr

我有一个像这样的数据框

ID <- c(101,101,101,102,102,102,103,103,103)
Pt_A <- c(50,100,150,20,30,40,60,80,90)
df <- data.frame(ID,Pt_A)

+-----+------+
| ID  | Pt_A |
+-----+------+
| 101 |   50 |
| 101 |  100 |
| 101 |  150 |
| 102 |   20 |
| 102 |   30 |
| 102 |   40 |
| 103 |   60 |
| 103 |   80 |
| 103 |   90 |
+-----+------+

我想创建2个新列,其值从Pt_A列计算。

df$Del_Pt_A <- NthRow(Pt_A) - 1stRow(Pt_A) grouped by ID, where n = 1,2,...n
df$Perc_Pt_A <- NthRow(Del_Pt_A) / 1stRow(Pt_A) grouped by ID, where n = 1,2,...n

这是我想要的输出

+-----+------+---------+-----------+
| ID  | Pt_A | Del_Pt_A | Perc_Pt_A|
+-----+------+---------+-----------+
| 101 |   50 | 0       | 0         |
| 101 |  100 | 50      | 1.0       |
| 101 |  150 | 100     | 2.0       |
| 102 |   20 | 0       | 0         |
| 102 |   30 | 10      | 0.5       |
| 102 |   40 | 20      | 1.0       |
| 103 |   60 | 0       | 0         |
| 103 |   80 | 20      | 0.3       |
| 103 |   90 | 30      | 0.5       |
+-----+------+---------+-----------+

我目前在MS Excel中获得了所需的结果,但我想学习在R中做到这一点,以提高我的工作效率。我遇到了dplyr,plyr,data.table等软件包,但我无法用它来解决它。有人可以帮我弄清楚如何解决这个问题。

2 个答案:

答案 0 :(得分:4)

这是一种data.table方式:

library(data.table)
setDT(df)[,`:=`(
    del       = Pt_A - Pt_A[1],
    perc      = Pt_A/Pt_A[1]-1
),by=ID]

给出了

    ID Pt_A del      perc
1: 101   50   0 0.0000000
2: 101  100  50 1.0000000
3: 101  150 100 2.0000000
4: 102   20   0 0.0000000
5: 102   30  10 0.5000000
6: 102   40  20 1.0000000
7: 103   60   0 0.0000000
8: 103   80  20 0.3333333
9: 103   90  30 0.5000000

答案 1 :(得分:2)

基础R中的另一个选项:

cbind(df,
      do.call(rbind,by(df,df$ID,
   function(x)
           setNames(data.frame(x$Pt_A-x$Pt_A[1],
                      x$Pt_A/x$Pt_A[1]-1),
                    c('Del_Pt_A','Perc_Pt_A')))))

#        ID Pt_A Del_Pt_A Perc_Pt_A
# 101.1 101   50        0 0.0000000
# 101.2 101  100       50 1.0000000
# 101.3 101  150      100 2.0000000
# 102.1 102   20        0 0.0000000
# 102.2 102   30       10 0.5000000
# 102.3 102   40       20 1.0000000
# 103.1 103   60        0 0.0000000
# 103.2 103   80       20 0.3333333
# 103.3 103   90       30 0.5000000

我正在使用:

  • by按组应用功能,结果是列表
  • do.call(rbind, list_by)将列表转换为data.frame
  • cbind将结果添加到初始data.frame