【问题标题】:add rows in a data.table but not when certain columns take same values在 data.table 中添加行,但在某些列采用相同值时不添加
【发布时间】:2016-07-13 23:04:56
【问题描述】:

我有一个带有 4 列的 data.table dat,例如(col1col2col3col4)。

输入数据:

structure(list(col1 = c(5.1, 5.1, 4.7, 4.6, 5, 5.1, 5.1, 4.7, 
4.6, 5), col2 = c(3.5, 3.5, 3.2, 3.1, 3.6, 3.5, 3.5, 3.2, 3.1, 
3.6), col3 = c(1.4, 1.4, 1.3, 1.5, 1.4, 3.4, 3.4, 1.3, 1.5, 1.4
), col4 = structure(c(1L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 4L, 4L), .Label = c("setosa", 
"versicolor", "virginica", "eer"), class = "factor")), .Names = c("col1", 
"col2", "col3", "col4"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"))

r
    col1 col2 col3   col4
 1:  5.1  3.5  1.4 setosa
 2:  5.1  3.5  1.4 setosa
 3:  4.7  3.2  1.3 setosa
 4:  4.6  3.1  1.5 setosa
 5:  5.0  3.6  1.4 setosa
 6:  5.1  3.5  3.4    eer
 7:  5.1  3.5  3.4    eer
 8:  4.7  3.2  1.3    eer
 9:  4.6  3.1  1.5    eer
10:  5.0  3.6  1.4    eer

我正在 col3 上为 col4 的每个唯一值执行以下操作

dat[ , r_new:= sum(col3, na.rm = T), .(col4)]    #syntax 1

因此,上面的 sytnax 正在创建一个新列 r_new,其值是通过将 col3 的值相加得到的,其中 col4 是相同的。因此,col4 的每个唯一值将在 r_new 列中具有唯一值。

我现在想要做的是和上面一样,但包括那些col1col2 采用相同值的行(如下所示)强>

dat[col1 is different OR col2 is different , r_new:= sum(col3, na.rm = T), .(col4)]

这会做什么,在对行执行 sum 函数时,它不会包括 col1col2 采用相同值的那些行。

如何在与 1 相同的语法中包含此条件?

预期输出:

    col1 col2 col3   col4 r_new
 1:  5.1  3.5  1.4 setosa   5.6
 2:  5.1  3.5  1.4 setosa   5.6
 3:  4.7  3.2  1.3 setosa   5.6
 4:  4.6  3.1  1.5 setosa   5.6
 5:  5.0  3.6  1.4 setosa   5.6
 6:  5.1  3.5  3.4    eer   7.6
 7:  5.1  3.5  3.4    eer   7.6
 8:  4.7  3.2  1.3    eer   7.6
 9:  4.6  3.1  1.5    eer   7.6
10:  5.0  3.6  1.4    eer   7.6

正如您在预期输出中看到的那样,setosa 第 1 行和第 2 行对col1col2 采用相同的值,对于err,第 6 行和第 7 行对col1 和@987654347 采用相同的值@,所以我们没有添加这些行(我们只考虑过一次)。不用担心col3(如果col1col2 采用相同的值,它将采用相同的值。

编辑:第二个输入:

structure(list(col1 = c(5.1, 5.1, 4.7, 4.6, 5, 5.1, 5.1, 4.7, 
4.6, 5.1), col2 = c(3.5, 3.5, 3.2, 3.1, 3.6, 3.5, 3.5, 3.2, 3.1, 
3.4), col3 = c(1.4, 1.4, 1.3, 1.5, 1.4, 3.4, 3.4, 1.3, 1.5, 3.4
), col4 = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), 
    count = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), r_new = c(5.6, 5.6, 
    5.6, 5.6, 5.6, 9.6, 9.6, 9.6, 9.6, 9.6)), .Names = c("col1", 
"col2", "col3", "col4", "count", "r_new"), row.names = c(NA, 
-10L), class = c("data.table", "data.frame"))

    col1 col2 col3 col4 count r_new
 1:  5.1  3.5  1.4    A     1   5.6
 2:  5.1  3.5  1.4    A     1   5.6
 3:  4.7  3.2  1.3    A     1   5.6
 4:  4.6  3.1  1.5    A     1   5.6
 5:  5.0  3.6  1.4    A     1   5.6
 6:  5.1  3.5  3.4    B     1   9.6
 7:  5.1  3.5  3.4    B     1   9.6
 8:  4.7  3.2  1.3    B     1   9.6
 9:  4.6  3.1  1.5    B     1   9.6
10:  5.1  3.4  3.4    B     1   9.6

编辑 2:第三个输入

   col1 col2 col3 col4 count r_new
 1:  5.1  3.5  1.4    A     1   5.6
 2:  5.1  3.5  1.4    A     1   5.6
 3:  4.7  3.2  1.3    A     1   5.6
 4:  4.6  3.1  1.5    A     1   5.6
 5:  5.0  3.6  1.4    A     1   5.6
 6:  5.1  3.5  3.4    B     1   6.2
 7:  5.1  3.5  3.4    B     1   6.2
 8:  4.7  3.2  1.3    B     1   6.2
 9:  4.6  3.1  1.5    B     1   6.2
10:  5.1  3.5  3.4    B     1   6.2


structure(list(col1 = c(5.1, 5.1, 4.7, 4.6, 5, 5.1, 5.1, 4.7, 
4.6, 5.1), col2 = c(3.5, 3.5, 3.2, 3.1, 3.6, 3.5, 3.5, 3.2, 3.1, 
3.5), col3 = c(1.4, 1.4, 1.3, 1.5, 1.4, 3.4, 3.4, 1.3, 1.5, 3.4
), col4 = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), 
    count = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), r_new = c(5.6, 5.6, 
    5.6, 5.6, 5.6, 6.2, 6.2, 6.2, 6.2, 6.2)), .Names = c("col1", 
"col2", "col3", "col4", "count", "r_new"), row.names = c(NA, 
-10L), class = c("data.table", "data.frame"))

【问题讨论】:

  • 不能提前过滤吗?
  • 你能显示dat 和预期的输出吗
  • @mtoto 我已经添加了示例。
  • @MattDowle 是的,它应该只是 6.2。 9.6答案由mtoto的答案给出。为了给他看,我照原样复制了结果。让我编辑它并写出正确的答案。
  • 没有。 col2 与第 10 行不同。因此,第 6 行和第 10 行是 col1 和 col2 的 2 个不同组合。只有 col1 和 col2 同时相同的那些行才需要考虑。

标签: r data.table aggregate reshape reshape2


【解决方案1】:

我们可以使用?data.table::duplicatedj 中子集col3

dat[, r_new := sum(col3[!duplicated(.SD, by = c("col1","col2"))], na.rm = T), by = col4]  

> dat
#      col1 col2 col3 col4 count r_new
# 1:  5.1  3.5  1.4    A     1   5.6
# 2:  5.1  3.5  1.4    A     1   5.6
# 3:  4.7  3.2  1.3    A     1   5.6
# 4:  4.6  3.1  1.5    A     1   5.6
# 5:  5.0  3.6  1.4    A     1   5.6
# 6:  5.1  3.5  3.4    B     1   6.2
# 7:  5.1  3.5  3.4    B     1   6.2
# 8:  4.7  3.2  1.3    B     1   6.2
# 9:  4.6  3.1  1.5    B     1   6.2
#10:  5.1  3.5  3.4    B     1   6.2

【讨论】:

  • 谢谢。我有另一个疑问,但我已将其作为另一个问题发布。 stackoverflow.com/questions/36233318/…你也能回答一下吗?
  • 是的。我正在试验,我发现了一个问题。请查看第二个 dput,您的解决方案不起作用。请告诉我,为什么?
  • 在第二个示例中,对于值 B,答案应该是 9.6 而不是 6.2。为什么会这样?
  • 好吧,情况并非相反。请在新的 dput 上应用您更新的解决方案(在问题中添加)。这次的答案应该是 6.2
  • @MattDowle 很好奇你的解决方案是什么。 data.table 的忠实粉丝,你们做得很棒!
【解决方案2】:

接受 mtoto 的答案,因为这更容易阅读,但这里有一个替代方案。

DT[, r_new:=unique(.SD,by=c("col1","col2"))[,sum(col3, na.rm=TRUE)], by=col4]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多