如何从具有唯一行的数据框中的列中减去一个值

3

标题很难解释问题。但是这里有一个数据框,你可以看到我有3个流名称。每个流名称都有3个唯一值。我希望将这些唯一值从在value列中找到的相应流的值中减去,然后将其附加到数据框中的一个名为error的新列中。

    stream  n  rates   means     column     value
1    Brooks 3   3.0  0.9629152      1    0.42707006
2   Siouxon 3   3.0  0.5831929      1    0.90503736
3  Speelyai 3   3.0  0.6199235      1    0.08554021
4    Brooks 4   7.5  0.9722707      1    1.43338843
5   Siouxon 4   7.5  0.5865031      1    0.50574543
6  Speelyai 4   7.5  0.6118634      1    0.32252396
7    Brooks 5  10.0  0.9637475      1    0.88984211
8   Siouxon 5  10.0  0.5804420      1    0.47501800
9  Speelyai 5  10.0  0.5959238      1    0.15079491
10   Brooks 6  13.0  0.9486575      1    1.32422105
11  Siouxon 6  13.0  0.5846854      1    0.39479684
12 Speelyai 6  13.0  0.5597146      1    0.37005941

这里的“独特”值是我想要从value列中减去的值。

> true.lwd.sp <- 0.583984402 (speelyai)
> true.lwd.sx <- 0.585852702 (souixon)
> true.lwd.br <- 0.944062036 (brooks)

感谢您的帮助。也许有一天我会知道如何完成所有这些简单的任务!
3个回答

5
我们可以创建一个新数据集,将“stream”列与新数据集中的相应列匹配,获取数字索引以从“df2”中获取相应的“value”,并从“df1”或原始数据集中减去。
 df1$error <- df1$value-df2$value[match(df1$stream, df2$stream)]
 df1
 #    stream n rates     means column      value       error
 #1    Brooks 3   3.0 0.9629152      1 0.42707006 -0.51699198
 #2   Siouxon 3   3.0 0.5831929      1 0.90503736  0.31918466
 #3  Speelyai 3   3.0 0.6199235      1 0.08554021 -0.49844419
 #4    Brooks 4   7.5 0.9722707      1 1.43338843  0.48932639
 #5   Siouxon 4   7.5 0.5865031      1 0.50574543 -0.08010727
 #6  Speelyai 4   7.5 0.6118634      1 0.32252396 -0.26146044
 #7    Brooks 5  10.0 0.9637475      1 0.88984211 -0.05421993
 #8   Siouxon 5  10.0 0.5804420      1 0.47501800 -0.11083470
 #9  Speelyai 5  10.0 0.5959238      1 0.15079491 -0.43318949
 #10   Brooks 6  13.0 0.9486575      1 1.32422105  0.38015901
 #11  Siouxon 6  13.0 0.5846854      1 0.39479684 -0.19105586
 #12 Speelyai 6  13.0 0.5597146      1 0.37005941 -0.21392499

数据

 df1 <- structure(list(stream = c("Brooks", "Siouxon", "Speelyai", 
 "Brooks", 
 "Siouxon", "Speelyai", "Brooks", "Siouxon", "Speelyai", "Brooks", 
 "Siouxon", "Speelyai"), n = c(3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 
 5L, 6L, 6L, 6L), rates = c(3, 3, 3, 7.5, 7.5, 7.5, 10, 10, 10, 
 13, 13, 13), means = c(0.9629152, 0.5831929, 0.6199235, 0.9722707, 
 0.5865031, 0.6118634, 0.9637475, 0.580442, 0.5959238, 0.9486575, 
 0.5846854, 0.5597146), column = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
 1L, 1L, 1L, 1L, 1L), value = c(0.42707006, 0.90503736, 0.08554021, 
 1.43338843, 0.50574543, 0.32252396, 0.88984211, 0.475018, 0.15079491, 
 1.32422105, 0.39479684, 0.37005941)), .Names = c("stream", "n", 
 "rates", "means", "column", "value"), class = "data.frame", 
 row.names = c("1", 
 "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))

 df2 <- data.frame(stream=c('Brooks', 'Siouxon', 'Speelyai'), 
      value=c(0.944062036, 0.585852702, 0.583984402), stringsAsFactors=FALSE)

但是,我该如何将这些值添加回数据框中呢?它们也需要在正确的行中。 - Christopher
1
@Christopher 你试过建议的答案看看会发生什么吗? - A. Webb
@A.Webb,是的,看起来它可以工作了,我的控制台会收到一堆值(由执行的计算结果产生),但是当我查看数据框时,这些值并不存在。 - Christopher

3

使用data.table的另一个选项,使用@akrun答案中的df2

library(data.table)
setDT(df1)[stream == df2$stream, error := value - df2$value]

 #    stream n rates     means column      value       error
 #1:   Brooks 3   3.0 0.9629152      1 0.42707006 -0.51699198
 #2:  Siouxon 3   3.0 0.5831929      1 0.90503736  0.31918466
 #3: Speelyai 3   3.0 0.6199235      1 0.08554021 -0.49844419
 #4:   Brooks 4   7.5 0.9722707      1 1.43338843  0.48932639
 #5:  Siouxon 4   7.5 0.5865031      1 0.50574543 -0.08010727
 #6: Speelyai 4   7.5 0.6118634      1 0.32252396 -0.26146044
 #7:   Brooks 5  10.0 0.9637475      1 0.88984211 -0.05421993
 #8:  Siouxon 5  10.0 0.5804420      1 0.47501800 -0.11083470
 #9: Speelyai 5  10.0 0.5959238      1 0.15079491 -0.43318949
#10:   Brooks 6  13.0 0.9486575      1 1.32422105  0.38015901
#11:  Siouxon 6  13.0 0.5846854      1 0.39479684 -0.19105586
#12: Speelyai 6  13.0 0.5597146      1 0.37005941 -0.21392499

你可以尝试使用 setkey 连接方法。这可能会更快。 - akrun
如何解释基准测试?akruns表达式的运行时间不可能是30.686分钟。 - Christopher
@Christopher 这是 microbenchmark 的估计值。要了解更多信息,请查看 ?microbenchmark - Veerendra Gadekar
1
жҲ‘дёҚзҹҘйҒ“зЎ®еҲҮзҡ„еҺҹеӣ пјҢдҪҶжҳҜmatchйқһеёёеҝ«гҖӮд№ҹи®ё==дјҡжӣҙж…ўгҖӮ - akrun
1
@Arun 好的,我会用更大的数据进行测试,无论如何还是谢谢!我已经删除了基准测试 :) - Veerendra Gadekar

1
Akrun是正确的,但你需要一些额外的代码来连接数据集。 请查看这个简单(但类似)的例子:
    library(dplyr)

  # your original dataset
    dt1 = data.frame(stream = c("A","B","C","A","B","C"),
                     value = c(5,6,7,8,9,10))

  # your dataset with the values for each case
    dt2 = data.frame(stream = c("A","B","C"),
                     truevalue = c(0.58, 0.57, 0.56))

  # join datasets and create the error variable
    result = dt1 %>% left_join(dt2, by="stream") %>% mutate(error = value - truevalue)

    result

重要的是确保两个数据集中流的名称匹配,这样连接才能正确执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接