r - 有条件地减去两个数据表

3

我有两个数据表,显示多个位置(由地理编码标识)的温度。

我想创建第三个数据表,基于它们之间的减法。以下是它们:

library(data.table)

# Generate random data:
geocode <- paste0("N", 1:10)
dates <- seq(as.Date("2000-01-01"), as.Date("2004-12-31"), by="month")
models <- c("A", "B", "C", "D", "E")
temp <- runif(length(geocode)*length(dates)*length(models), min=0, max=30)
dt1 <- data.table(expand.grid(Location=geocode,Date=dates,Model=models),Temperature=temp)


ref <- runif(length(geocode), min=0, max=30)
dt2 <- data.table(expand.grid(Location=geocode), Temperature=ref)

我希望能够有条件地从dt1中减去dt2。对于每个位置(地理编码),我想将dt2中的温度从dt1中的温度中减去,保留其他列(DateModel)。

如何实现呢?如果只是单个数据表,我知道如何做,但我以前从未尝试过在两个不同的数据表上进行代数运算。

2个回答

5
我认为这个可以运行:
dt1[dt2, on=.(Location), td := x.Temperature - i.Temperature, by=.EACHI]

      Location       Date Model Temperature          td
   1:       N1 2000-01-01     A    3.949276 -19.2110455
   2:       N2 2000-01-01     A    2.811684 -11.6405195
   3:       N3 2000-01-01     A   24.069659  13.6159779
   4:       N4 2000-01-01     A   25.809426  -1.8793405
   5:       N5 2000-01-01     A   25.193624  19.6812965
  ---                                                  
2996:       N6 2004-12-01     E   24.298463   4.0218859
2997:       N7 2004-12-01     E    1.488011 -26.4472283
2998:       N8 2004-12-01     E   27.489108   5.6525076
2999:       N9 2004-12-01     E    3.487664  -5.9926003
3000:      N10 2004-12-01     E    8.523718  -0.7559126

肉眼检查...

dt2[dt1[1:5], on=.(Location), .(Location, t1 = i.Temperature, t2 = x.Temperature)]

   Location        t1        t2
1:       N1  3.949276 23.160321
2:       N2  2.811684 14.452204
3:       N3 24.069659 10.453681
4:       N4 25.809426 27.688766
5:       N5 25.193624  5.512328

我觉得没问题。


工作原理

更新连接的语法为x[i,v := expr,by=.EACHI]。在表达式中,前缀i.*x.*可用于明确从哪些列中获取数据。

by=.EACHI可能是不必要的,但我通常会使用它。


1
谢谢您的建议,它满足了我的需求!还有感谢您的解释。 - thiagoveloso

3

合并左连接),然后进行修改

library(dplyr)
dt3 <- left_join(dt1, dt2, by="Location") %>%
          mutate(desired=Temperature.x-Temperature.y)

输出

  Location       Date Model Temperature.x Temperature.y     desired
1       N1 2000-01-01     A      4.158847     17.531085 -13.3722373
2       N2 2000-01-01     A      9.644764     23.184142 -13.5393783
3       N3 2000-01-01     A      4.644948     20.946587 -16.3016384
4       N4 2000-01-01     A      3.966845     25.232795 -21.2659502
5       N5 2000-01-01     A      6.639178     29.325365 -22.6861873
6       N6 2000-01-01     A      6.791424      6.957811  -0.1663875

取消选择 Temperature.x 和 Temperature.y
dt3 <- dt3 %>% select(-Temperature.x, -Temperature.y)

感谢您提供的第一个答案,顺便说一下它很好用!但是,我需要坚持使用data.table解决方案,因为我仍然需要在数据集上执行更多操作,并且我对dplyr不是很熟悉... - thiagoveloso
1
没问题。我也给 data.table 的解决方案点了赞。 - CPak

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