【问题标题】:conditional insertion of a new row in a data.frame with R使用 R 有条件地在 data.frame 中插入新行
【发布时间】:2015-04-13 05:10:10
【问题描述】:

我有一个这样的数据框:

ID  Exp1 Exp2 Value1
AAA 5    6    7
AAA 4    8    8
BBB 3    5    9
BBB 6    7    4
CCC 2    5    6
....

我想在每次重复 ID 后创建一个新行,并对以前的结果进行求和,如下所示:

ID      Exp1 Exp2 Value1
AAA     5    6    7
AAA     4    8    8
AAA.1   9    14   15
BBB     3    5    9
BBB     6    7    4
BBB.1   9    12   13
CCC     2    5    6
...

我的问题是我无法编写代码在相同的 ID 之后插入新行。

    > for (i in 1:nrow(Data)) {   
    > temp1 <- Data[Data$ID == Data$ID[i],]   

但不知道如何继续... 有什么想法吗?

更新: 原始数据如何..

 GeneNames  Original    ID2          Com.   Ratio   Cyt     Nuc
 YWHAB  CL84Contig6     1433B_HUMAN  -0.2   0.6    1063.3   671.3
 YWHAB  CL84Contig4     1433B_HUMAN  -0.3   0.5    59.0     30.5
 YWHAE  CL1665Contig1   1433E_HUMAN  -0.3   0.5    2784.6   1490.1
 YWHAE  CL1665Contig4   1433E_HUMAN   0.1   1.2    2.1      4.8
 YWHAH  dsrrswapns      1433F_HUMAN   0.0   0.0    0.0      0.0
 YWHAG  CL2762Contig2   1433G_HUMAN  -0.3   0.4    39.5     17.7
 YWHAG  CL2762Contig3   1433G_HUMAN   0.0   0.0    0.0      0.0

我想怎么做...

GeneNames   Original    ID2          Com.   Ratio   Cyt     Nuc
 YWHAB  CL84Contig6     1433B_HUMAN  -0.2   0.6    1063.3   671.3
 YWHAB  CL84Contig4     1433B_HUMAN  -0.3   0.5    59.0     30.5
YWHAB.1 CL84Contig6     1433B_HUMAN  -0.2   0.6    1122.4   701.8
 YWHAE  CL1665Contig1   1433E_HUMAN  -0.3   0.5    2784.6   1490.1
 YWHAE  CL1665Contig4   1433E_HUMAN   0.1   1.2    2.1      4.8
YWHAE.1 CL1665Contig1   1433E_HUMAN  -0.3   0.5    2786.6   1494.9

我有一个 data.frame: 13044 obs。 94 个变量:这 94 个变量是 num 和 chr 列。 我想仅对来自同一 GeneNames 的 Cyt 和 Nuc 的值求和,并将它们写入 GeneName 命名为“GeneName.1”的新行。每个 GeneName 的其余列都不相同。我宁愿将它们留空或复制相同 GeneName 的第一列,如示例中所示..

【问题讨论】:

  • 嗯,您可以将它们添加到最后,然后按 ID 排序以获得所需的结果。

标签: r insert row


【解决方案1】:

您可以使用data.table 执行此操作。将“data.frame”转换为“data.table”(setDT)。创建一个按“ID”分组的“NA”行(.SD[1:(.N+1)]),将每个“ID”的“NA”元素替换为sumlapply(.SD,...)

library(data.table)
setDT(df1)[, .SD[1:(.N+1)], ID][, lapply(.SD, function(x)
        replace(x, is.na(x), sum(x, na.rm=TRUE))) , ID]
#      ID Exp1 Exp2 Value1
#1: AAA    5    6      7
#2: AAA    4    8      8
#3: AAA    9   14     15
#4: BBB    3    5      9
#5: BBB    6    7      4
#6: BBB    9   12     13
#7: CCC    2    5      6
#8: CCC    2    5      6

或者您可以rbind 具有“总和”按“ID”组的列。这按“ID”排序

 setDT(df1)[, rbind(.SD,lapply(.SD, sum)), ID]
 #    ID Exp1 Exp2 Value1
 #1: AAA    5    6      7
 #2: AAA    4    8      8
 #3: AAA    9   14     15
 #4: BBB    3    5      9
 #5: BBB    6    7      4
 #6: BBB    9   12     13
 #7: CCC    2    5      6
 #8: CCC    2    5      6

更新

基于新的数据集,试试

  DT1 <- setDT(df1)[, .SD[1:(.N+1)], GeneNames][, 6:7 := lapply(.SD, 
       function(x) replace(x, is.na(x), sum(x, na.rm=TRUE))), 
             GeneNames, .SDcols=6:7]
  DT1[, 2:5 := lapply(.SD, function(x) replace(x, is.na(x),
             x[1L])), GeneNames, .SDcols=2:5][]
  #   GeneNames      Original         ID2 Com. Ratio    Cyt    Nuc
  #1:     YWHAB   CL84Contig6 1433B_HUMAN -0.2   0.6 1063.3  671.3
  #2:     YWHAB   CL84Contig4 1433B_HUMAN -0.3   0.5   59.0   30.5
  #3:     YWHAB   CL84Contig6 1433B_HUMAN -0.2   0.6 1122.3  701.8
  #4:     YWHAE CL1665Contig1 1433E_HUMAN -0.3   0.5 2784.6 1490.1
  #5:     YWHAE CL1665Contig4 1433E_HUMAN  0.1   1.2    2.1    4.8
  #6:     YWHAE CL1665Contig1 1433E_HUMAN -0.3   0.5 2786.7 1494.9
  #7:     YWHAH    dsrrswapns 1433F_HUMAN  0.0   0.0    0.0    0.0
  #8:     YWHAH    dsrrswapns 1433F_HUMAN  0.0   0.0    0.0    0.0
  #9:     YWHAG CL2762Contig2 1433G_HUMAN -0.3   0.4   39.5   17.7
  #10:     YWHAG CL2762Contig3 1433G_HUMAN  0.0   0.0    0.0    0.0
  #11:     YWHAG CL2762Contig2 1433G_HUMAN -0.3   0.4   39.5   17.7

或使用rbind 方法

 DT1 <- setDT(df1)[, rbind(.SD, lapply(.SD, sum)), GeneNames, .SDcols=6:7]
 setkey(df2, GeneNames, Cyt, Nuc)[DT1]

然后像以前一样将第 2:5 列中的 NA 更改为第一行值

数据

 df1 <- structure(list(ID = c("AAA", "AAA", "BBB", "BBB", "CCC"), 
 Exp1 = c(5L, 4L, 3L, 6L, 2L), Exp2 = c(6L, 8L, 5L, 7L, 5L), Value1 = 
 c(7L, 8L, 9L, 4L, 6L)), .Names = c("ID", "Exp1", "Exp2", "Value1"), 
 class = "data.frame", row.names = c(NA, -5L))

【讨论】:

  • 考虑到他试图将行插入数据框,这太复杂了。除了代码高尔夫之外,这对于任何事情来说都过于复杂了。但是,是的,oneliners 确实有效。
  • dplyr 中是否有与 [, .SD[1:(.N+1)], ID] 等效的内容?我喜欢这种方法,但我在dplyr 中还看不到它的翻译。
  • @jazzurro 我认为您可以使用rbind 方法并使用arrange
  • @akrun 非常感谢!这正是我想要的...问题是实际数据也包含更多 chr 列,这会带来问题...是否可以仅对 Exp1 和 Exp2 列求和?
  • @akrun 不确定速度,但这就是我现在所拥有的。 group_by(ana, GeneNames) %&gt;% do(if(length(.$GeneNames) &gt; 1) rbind(.[,-1], NA) else(.[,-1])) %&gt;% mutate_each(funs(replace(., !complete.cases(.), .[1])), 2:5) %&gt;% mutate_each(funs(replace(., !complete.cases(.), sum(., na.rm = TRUE))), Cyt:Nuc)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2017-08-16
  • 2011-03-19
  • 2016-10-01
  • 2023-04-10
相关资源
最近更新 更多