【问题标题】:Exchange data.table columns with most prevalent value of columns使用最普遍的列值交换 data.table 列
【发布时间】:2020-02-14 15:12:36
【问题描述】:

我有数据

test = data.table(
  a = c(1,1,3,4,5,6), 
  b = c("a", "be", "a", "c", "d", "c"), 
  c = rep(1, 6)
)

我希望获取列 a 的唯一值,将其存储在另一个 data.table 中,然后用这些剩余列中最普遍的值填充剩余列,这样我的结果data.table 将是:

test2 = data.table(a = c(1,3,4,5,6), b = "a", c = 1)

be 列有相同数量的“a”和“c”,但在这些情况下选择哪个并不重要。

目前的尝试:

test2 = unique(test, by = "a")
test2[, c("b", "c") := lapply(.SD, FUN = function(x){test2[, .N, by = x][order(-N)][1,1]}), .SDcols = c("b", "c")]

编辑:我希望有一个通用的解决方案,它与我指定列为“唯一”的函数兼容,而其余列具有单个最普遍的值。因此我使用 lapply 和 .SD =)

EDIT2:正如@MichaelChirico 指出的那样,我们如何保持课程。使用以下 data.table 的一些解决方案不起作用,尽管@chinsoon12 的解决方案确实有效:

test = data.table(a = c(1,1,3,4,5,6), 
                  b = c("a", "be", "a", "c", "d", "c"), 
                  c = rep(1, 6),
                  d = as.Date("2019-01-01"))

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    另一种选择:

    dtmode <- function(x) x[which.max(rowid(x))]
    test[, .(A=unique(A), B=dtmode(B), C=dtmode(C))] 
    

    数据:

    test = data.table(
        A = c(1,1,3,4,5,6), 
        B = c("a", "be", "a", "c", "d", "c"), 
        C = rep(1, 6)
    )
    

    【讨论】:

    • 啊,这很优雅,谢谢!我不知道rowid()
    【解决方案2】:

    这不是一个干净的方法,但它有效。

    test = data.frame(a = c(1,1,3,4,5,6), b = c("a", "be", "a", "c", "d", "c"), c = rep(1, 6))
    
    a = unique(test$a)
    b = tail(names(sort(table(test$b))), 1)
    c = tail(names(sort(table(test$c))), 1)
    
    test2 = cbind(a,b,c)
    

    输出是这样的:

    > test2
         a   b   c  
    [1,] "1" "c" "1"
    [2,] "3" "c" "1"
    [3,] "4" "c" "1"
    [4,] "5" "c" "1"
    [5,] "6" "c" "1"
    > 
    

    【讨论】:

    • 感谢您的帮助!不幸的是,这不是我想要的。我不想硬编码任何东西=)
    • @MichaelChirico:抱歉,这不是很清楚,我同意。我的意思是:1)变量名称未明确写在代码中的解决方案,如第 2、3 和 4 行。2)适用于比我在示例中说明的更多列的解决方案,即我想要一个 data.table .SD + .SDcols 解决方案
    【解决方案3】:

    @EmreKiratli 非常接近我会做的事情:

    test[ , c(
      list(a = unique(a)),
      lapply(.SD, function(x) as(tail(names(sort(table(x))), 1L), class(x)))
    ), .SDcols = !'a']
    

    as(., class(x))部分是因为R中的names总是character,所以我们必须转换回原来的x类。

    你可能更喜欢magrittr 形式,因为它有很多嵌套函数:

    library(magrittr)
    test[ , c(
      list(a = unique(a)),
      lapply(.SD, function(x) {
        table(x) %>% sort %>% names %>% tail(1L) %>% as(class(x))
      })
    ), .SDcols = !'a']
    

    【讨论】:

    • 非常感谢!关于课程的好点。当我们在 data.table test 中有一个日期列时,我们的代码实际上都不起作用。 test = data.table(a = c(1,1,3,4,5,6), b = c("a", "be", "a", "c", "d", "c" ), c = rep(1, 6), d = as.Date("2019-01-01"))
    【解决方案4】:

    我能够提出一个好的解决方案,但如果有人可以做得更优雅,例如不通过下面的 refLevel 存储列表的步骤,请告诉我!我对正确学习 data.table 非常感兴趣!

    #solution:
    test = data.table(a = c(1,1,3,4,5,6), b = c("a", "be", "a", "c", "d", "c"), c = rep(1, 6))
    test2 = unique(test, by="a")
    funPrev = function(x){unlist(as.data.table(x)[, .N, by=x][order(-N)][1,1], use.names = F)}
    refLevel = lapply(test[, c("b", "c")], funPrev)
    test2[, c("b", "c") := refLevel]
    

    ...并使用函数(如果有人看到任何不必要的步骤,请告诉我):

    genData = function(dt, var_unique, vars_prev){
    
      data = copy(dt)
      data = unique(data, by = var_unique)
    
      funPrev = function(x){unlist(as.data.table(x)[, .N, by=x][order(-N)][1,1], use.names = F)}
    
      refLevel = lapply(dt[, .SD, .SDcols = vars_prev], funPrev)
      data[, (vars_prev) := refLevel] 
    
      return(data)
    }
    test2 = genData(test, "a", c("b", "c"))
    

    【讨论】:

      【解决方案5】:

      这是另一种变体,人们可能会发现它不太复杂,但更具可读性。它本质上是 chinsoon12 的 rowid 方法,可推广到任意数量的列。课程也被保留了。

      test = data.table(a = c(1,1,3,4,5,6), 
                        b = c("a", "be", "a", "c", "d", "c"), 
                        c = rep(1, 6),
                        d = as.Date("2019-01-01"))
      test2 = unique(test, by = "a")
      for (col in setdiff(names(test2), "a")) test2[[col]] = test2[[col]][which.max(rowid(test2[[col]]))]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-18
        • 2012-01-12
        • 1970-01-01
        • 2014-01-20
        • 2019-05-06
        • 1970-01-01
        • 2021-06-14
        相关资源
        最近更新 更多