【问题标题】:Subtracting data.frames and data.tables of different sizes减去不同大小的data.frames和data.tables
【发布时间】:2015-07-28 14:18:24
【问题描述】:

两个相同维度的data.frames可以用R相减

df1 - df2

但我想减去两个不同维度的data.frames,比如

df1 <- data.frame(V1=1:5)
df2 <- data.frame(V1=1:5, V2=6:10)

df1-df2

Error in Ops.data.frame(df1, df2) : 
  ‘-’ only defined for equally-sized data frames

这种减法可以使用 for 循环来实现,但我正在寻找任何已经建立的函数。谢谢

已编辑

如果必须减去两个不同维度的data.tables呢?

library(data.table)
dt1 <- data.table(V1=1:5)
dt2 <- data.table(V1=1:5, V2=6:10)

dt1-dt2

Error in `[.data.table`(dt1, row(dt2), ) : 
  i is invalid type (matrix). Perhaps in future a 2 column matrix could return a list of elements of DT (in the spirit of A[B] in FAQ 2.14). Please let datatable-help know if you'd like this, or add your comments to FR #1611.
dt1[row(dt2),]-dt2

【问题讨论】:

  • 试试df1[row(df2),]-df2
  • 或者在你的情况下只是df1$V1-df2。但@akruns 的建议可能更笼统
  • 优秀的@akrun。这更适合我的情况。谢谢
  • 我认为如果df1df2 都有更多的列,它应该类似于unlist(df1[row(df2),])-df2
  • @akrun:请更改您的评论以回答并查看我的编辑。

标签: r dataframe subtraction


【解决方案1】:

我们可以通过使两个数据集具有相同的长度来做到这一点,以便我们可以逐个元素地比较每个数据集。在给出的示例中,'df1' 有 1 列 5 行,而 'df2' 是 2 列 5 行。这个想法是使“df1”具有 10 个元素或 2 列 5 行以匹配“df2”的尺寸。这可以通过rep 轻松完成,或者一个方便的函数是row

  df1[row(df2),]-df2

只是为了更清楚

 row(df2)
 #     [,1] [,2]
 #[1,]    1    1
 #[2,]    2    2
 #[3,]    3    3
 #[4,]    4    4
 #[5,]    5    5

给出'df2'每一行的行索引。通过做

 df1[row(df2),]
 #[1] 1 2 3 4 5 1 2 3 4 5

我们将每个行元素复制两次。鉴于数据集按列执行此操作,它的发生如下所示

 df1[c(row(df2)[,1],row(df2)[,2]),]

这可以从df2中减去

 df1[row(df2),]-df2
 #  V1 V2
 #1  0 -5
 #2  0 -5
 #3  0 -5
 #4  0 -5
 #5  0 -5

正如@David Arenburg 所提到的,对于具有多列的两个数据集,这将返回错误的结果。因此,如果您要从多列数据集(“df2”)中从“df1”(具有多列)中减去单列,那么选择该列并从“df2”中减去可能更通用(感谢@David阿伦堡的代码)

 df1$V1-df2
 #  V1 V2
 #1  0 -5
 #2  0 -5
 #3  0 -5
 #4  0 -5
 #5  0 -5

由于循环效应而起作用,即'V1'列元素将从'df2'的第一列中减去,然后它将再次从第一个元素开始从'df2'的第二列中减去(假设两个数据集具有相同的数量或行数)。


对于带有data.table(“dt1”的单列)的第二个示例,一个选项是

dt1[,rep(names(dt1), ncol(dt2)),with=FALSE]-dt2
#   V1 V1
#1:  0 -5
#2:  0 -5
#3:  0 -5
#4:  0 -5
#5:  0 -5

【讨论】:

  • 我仍然对这与 df1$V1-df2 有何不同感到困扰?这个解决方案不适用于df1 &lt;- data.frame(V1=1:5, V2 = 6:10) ; df2 &lt;- data.frame(V1=1:5, V2=6:10, V3 = 11:15),除非包装成unlist(df1[row(df2),])-df2。对 OP 真正想要什么有点困惑。
  • @DavidArenburg 在您提供的示例中,预期输出是什么
  • unlist(df1[row(df2),])-df2 的输出我猜,不是吗?
  • @DavidArenburg 不知道。我猜 OP 可能想要在 'df1' 的每一列与 'df2' 中的所有其他列之间进行区分。 (只是猜测)
  • @DavidArenburg 你还记得 Frank 的代码打高尔夫球来复制 data.table 中的列吗?类似dt1[] &lt;- ..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 2022-11-23
  • 2011-05-28
  • 2019-12-07
  • 1970-01-01
相关资源
最近更新 更多