【问题标题】:Ifelse statement with nested data.table statements带有嵌套 data.table 语句的 ifelse 语句
【发布时间】:2016-06-13 18:22:19
【问题描述】:

这是我的数据框。

library(data.table)
     dt <- fread('
 Name     Video   Webinar Meeting Conference  Level  NextStep
  John       1         0        0       0      1     Webinar,Meeting,Conference
  John       1         1        0       0      1     Meeting,Conference
  John       1         1        1       0      2     Conference      
  Tom        0         0        1       0      1     Webinar,Conference,Video
  Tom        0         0        1       1      2     Webinar,Video   
  Kyle       0         0        0       1      2     Webinar,Meeting,Video

                                ')

我正在通过这样做来创建下一步列

dt[, nextstep := paste0(names(.SD)[.SD==0], collapse = ','), 1:nrow(DT), .SDcols = 2:5][]

根据这里的解决方案Making a character string with column names with zero values

现在我想根据“级别”字段更改元素在下一步列中的显示顺序。例如,如果是 1 级,我希望会议在网络研讨会和会议之前出现。如果是第 2 级,我希望视频始终显示在最后。这是我的尝试。

 dt<-dt[, NextStep := ifelse(Level1=="Level0",
(paste0(names(.SD)[.SD==0], collapse = ';'), 1:nrow(dt), .SDcols = c(5,2,3,4)),
      ifelse(EngagementLevel1=="Level2",
(paste0(names(.SD)[.SD==0], collapse = ';'), 1:nrow(dt), .SDcols = c(3,4,5,2))))]

我只是想根据“级别”字段对“下一步”字段中的元素重新排序。衷心感谢您的帮助!

【问题讨论】:

    标签: r if-statement data.table dplyr


    【解决方案1】:

    嗯,你可以把你喜欢的顺序放在某个地方:

    levelmap = data.table(Level = 1:2, ord = list(
        c("Conference", "Webinar", "Meeting", "Video"), 
        c("Webinar", "Meeting", "Conference", "Video")
    ))
    

    然后使用你之前的方法:

    DT[, r := .I]
    for (ii in seq(nrow(levelmap)))
        DT[ Level == levelmap$Level[ii], 
          ns := paste0(names(.SD)[.SD==0], collapse = ',')
        , by = r, .SDcols = levelmap$ord[[ii]] ][]
    

    但实际上,我认为您根本不应该这样做(这个问题和上一个问题都有什么)。这是一种处理数据的混乱方式。

    评论整洁的数据。为了澄清我的意思,我建议查看 Hadley Wickham 的 paper on tidy data。这里整洁的数据大概是这样的:

    myDT = melt(
      DT[, !"NextStep", with=FALSE][, Seq := 1:.N, by=Name], 
      id.var = c("Name", "Seq", "Level"))
    
        Name Seq Level   variable value
     1: John   1     1      Video     1
     2: John   2     1      Video     1
     3: John   3     2      Video     1
     4:  Tom   1     1      Video     0
     5:  Tom   2     2      Video     0
     6: Kyle   1     2      Video     0
     7: John   1     1    Webinar     0
     8: John   2     1    Webinar     1
     9: John   3     2    Webinar     1
    10:  Tom   1     1    Webinar     0
    11:  Tom   2     2    Webinar     0
    12: Kyle   1     2    Webinar     0
    13: John   1     1    Meeting     0
    14: John   2     1    Meeting     0
    15: John   3     2    Meeting     1
    16:  Tom   1     1    Meeting     1
    17:  Tom   2     2    Meeting     1
    18: Kyle   1     2    Meeting     0
    19: John   1     1 Conference     0
    20: John   2     1 Conference     0
    21: John   3     2 Conference     0
    22:  Tom   1     1 Conference     0
    23:  Tom   2     2 Conference     1
    24: Kyle   1     2 Conference     1
        Name Seq Level   variable value
    

    或者您甚至可能会删除所有零或一的行(因为它们相当多余)。

    我们的想法是,这将是您用于进行任何分析或构建任何汇总表的主要数据。在您的情况下,目标是一个汇总表(据我所知),例如

    library(magrittr)
    res = myDT[levelmap, on="Level"][, .( NextStep = 
      variable[value == 0] %>% factor(levels = ord[[1]]) %>% sort %>% toString
    ), keyby=.(Name, Seq, Level)]
    
       Name Seq Level                     NextStep
    1: John   1     1 Conference, Webinar, Meeting
    2: John   2     1          Conference, Meeting
    3: John   3     2                   Conference
    4: Kyle   1     2      Webinar, Meeting, Video
    5:  Tom   1     1   Conference, Webinar, Video
    6:  Tom   2     2               Webinar, Video
    

    如果您真的想要 0/1 列,您还可以将它们包含在 dcast 中(将数据从长转换为宽):

    cbind(
      res, 
      dcast(myDT, Name + Seq ~ variable, value.var="value")[, !c("Name", "Seq"), with=FALSE])
    

    【讨论】:

    • 非常感谢您回答 Frank。当您说这是一种处理数据的混乱方式时,请告诉我您指的是什么。你的意思是我生成下一步列的方式吗?
    • @gibbz00 基本上,我的意思是您不应该对宽格式的数据进行分析(您将“数据”存储为列名)。
    • 非常感谢您的详细解释!我从你身上学到了很多。
    猜你喜欢
    • 2013-08-03
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多