在一定间隔后添加行并将数据复制到R中

时间:2014-01-10 14:13:03

标签: r dataframe

我在数据框中有每个深度的采样数据。现在必须将原始深度内插到新的深度,为此我在不同的数据帧中有信息。 所以需要做的是:

  • 在每个样本类型(即a,b,)
  • 之后创建一个新行
  • 从上面复制“价值”
  • 将最后一个sam_bot(底部)作为新的sam_top
  • 将dat2 sam_new_bot作为新的sam_bot

第一个data.frame看起来像这样:

dat1 = data.frame(Samp = rep(letters[1:4], each = 4), 
             sam_top = seq(1:4), 
             sam_bot = seq(2,5), 
             value = runif(16), 
             stringsAsFactors = F) 

给了我:

   Samp sam_top sam_bot      value
1     a       1       2 0.75864637
2     a       2       3 0.44056410
3     a       3       4 0.18105700
4     a       4       5 0.67938119
5     b       1       2 0.75444497
6     b       2       3 0.59411439
7     b       3       4 0.11755459
8     b       4       5 0.70143005
9     c       1       2 0.44234565
10    c       2       3 0.82872824

第一个具有新深度的第二个数据框如下所示:

dat2 <- read.table(text = "Samp sam_new_bot
a      6
b      7
c      6
d      7.5", header = TRUE)

> dat2
  Samp   sam_new_bot
1    a         6.0
2    b         7.0
3    c         6.0
4    d         7.5

结果应如下所示:

   Samp sam_top sam_bot      value
1     a       1       2 0.75864637
2     a       2       3 0.44056410
3     a       3       4 0.18105700
4     a       4       5 0.67938119
5     a       5       6 0.67938119
5     b       1       2 0.75444497
6     b       2       3 0.59411439
7     b       3       4 0.11755459
8     b       4       5 0.70143005
9     b       5       7 0.70143005
10    c       1       2 0.44234565

请注意,data.frame没有固定的间隔,因此可以有任意数量的Samp。

更新 我设法插入行:

do.call(rbind, by(dat1, dat1$Samp, rbind, dat1[1,]))

现在我的理解是,我必须用x的函数替换dat1 [1]部分,但不知怎的,我不能把它们放在一起。

2 个答案:

答案 0 :(得分:1)

以下是data.table的解决方案。逻辑如下:

  1. 获取每个sam_top的最大Samp,以及相应的值
  2. 将其合并到dat2以获取新sam_bot
  3. 中的每一个新sam_top
  4. 回到dat1
  5. 答案与您的答案看起来并不完全相同(因为我使用了您的数据创建代码):

    library(data.table)
    dat1 <- data.table(dat1)
    dat1.sub <- dat1[  # get new sam_top, as well as last value for Samp
      order(sam_top), 
      list(sam_top=max(sam_bot), value=tail(value, 1L)), 
      by=Samp
    ]
    dat2.sub <- merge(dat1.sub, dat2, by="Samp")[, c(1, 2, 4, 3), with=F] # match to `dat2`
    rbind(dat1, unname(as.list(dat2.sub)))[order(Samp, sam_top)]  # now rbind back and order
    #     Samp sam_top sam_bot      value
    # 1:     a       1       2 0.37475446
    # 2:     a       2       3 0.87263241
    # 3:     a       3       4 0.53154291
    # 4:     a       4       5 0.41648329
    # 5:     a       5       6 0.41648329
    # 6:     b       1       2 0.36251215
    # 7:     b       2       3 0.33083137
    # 8:     b       3       4 0.03237498
    # 9:     b       4       5 0.75553453
    # 10:    b       5       7 0.75553453
    # 11:    c       1       2 0.98819386
    # 12:    c       2       3 0.95251107
    # 13:    c       3       4 0.35680588
    # 14:    c       4       5 0.34674393
    # 15:    c       5       6 0.34674393
    # 16:    d       1       2 0.19573338
    # 17:    d       2       3 0.59690127
    # 18:    d       3       4 0.87038993
    # 19:    d       4       5 0.88751762
    # 20:    d       5       7 0.88751762
    

答案 1 :(得分:1)

使用您对dat1dat2的定义:

dat3 <- with(dat2,data.frame(Samp, sam_top=NA, sam_bot=sam_new_bot, value=NA))
dat3         <- dat3[dat3$Samp %in% dat1$Samp,]        # only use Samp in dat1
dat3$sam_top <- aggregate(sam_bot~Samp,dat1,tail,1)$sam_bot
dat3$value   <- aggregate(value~Samp,dat1,tail,1)$value
final        <- rbind(dat1,dat3)
final        <- final[order(final$Samp,final$sam_top),]

产地:

final
#    Samp sam_top sam_bot     value
# 1     a       1       2 0.7586464
# 2     a       2       3 0.4405641
# 3     a       3       4 0.1810570
# 4     a       4       5 0.6793812
# 11    a       5       6 0.6793812
# 5     b       1       2 0.7544450
# 6     b       2       3 0.5941144
# 7     b       3       4 0.1175546
# 8     b       4       5 0.7014301
# 12    b       5       7 0.7014301
# 9     c       1       2 0.4423456
# 10    c       2       3 0.8287282
# 13    c       3       6 0.8287282

行名称不同,但希望这并不重要。

此代码根据您的dat3创建一个包含额外行模板的数据框dat2,然后根据您的条件在模板中设置sam_topvalue,然后将这些行添加到原始dat1,创建final,然后重新排序最终以匹配您的结果。请注意在tail(...)中使用aggregate(...)函数来提取系列中的最后一行。

最后,您的dat2有一个Samp="d",而您的dat1没有{{1}};这就是第二行代码的原因。