【问题标题】:Loop to identify data location in a Dataframe, and populate to new Dataframe (R)循环识别数据帧中的数据位置,并填充到新的数据帧(R)
【发布时间】:2018-07-27 00:42:16
【问题描述】:

所以我有一个用户 ID 的数据框作为带有行的列(对应于周期间隔)和二进制变量(事件发生的地方),如下所示:

date Id1 Id2 id3 id4 id5

row1  1   0   0   1   0
row2  0   0   1   1   0
row3  0   1   0   0   1
row4  1   1   0   0   0
row5  0   0   1   1   1  
...

我正在尝试构建一个循环,该循环遍历每一列的每一行,该循环用 1 标识任何单元格,并使用每次出现的行号填充一个新数据框,例如:

  occ. Id1 Id2 id3 id4 id5 
  1    1    3   2   1   3 
  2    4    4   5   2   5
  3                 5    
  4
  5

如果有人能够提供帮助,我很迷茫如何解决这个问题?

【问题讨论】:

  • 您的第二帧并不是真正的帧,因为每列的长度不同。此外,您的示例框架不匹配,您可以编辑您的问题以使其具有代表性吗?
  • 最好存储在list,例如lapply(df[, -1], function(x) which(x == 1))
  • @r2evans - 更新!

标签: r loops dataframe


【解决方案1】:

您可以将reshape::melt 与来自tidyversespread 一起使用

reshape::melt(df)%>%filter(.,value==1)%>%group_by(variable)%>%mutate(n=row_number())%>%spread(variable,date)
# A tibble: 3 x 7
  value     n    Id1    Id2    id3    id4    id5
* <int> <int> <fctr> <fctr> <fctr> <fctr> <fctr>
1     1     1   row1   row3   row2   row1   row3
2     1     2   row4   row4   row5   row2   row5
3     1     3     NA     NA     NA   row5     NA

【讨论】:

    【解决方案2】:

    这是一个使用tidyverse的选项

    library(tidyverse)
    gather(df1, key, val, Id1:id5) %>%
         filter(val != 0) %>% 
         mutate(val = readr::parse_number(date)) %>% 
         spread(key, val) %>% 
         mutate_at(vars(Id1:id5), funs(c(.[!is.na(.)], .[is.na(.)]))) %>%
         rename(occ = date) %>%
         mutate( occ = readr::parse_number(occ))
    #   occ Id1 Id2 id3 id4 id5
    #1   1   1   3   2   1   3
    #2   2   4   4   5   2   5
    #3   3  NA  NA  NA   5  NA
    #4   4  NA  NA  NA  NA  NA
    #5   5  NA  NA  NA  NA  NA
    

    数据

    df1 <- structure(list(date = c("row1", "row2", "row3", "row4", "row5"
    ), Id1 = c(1L, 0L, 0L, 1L, 0L), Id2 = c(0L, 0L, 1L, 1L, 0L), 
    id3 = c(0L, 1L, 0L, 0L, 1L), id4 = c(1L, 1L, 0L, 0L, 1L), 
    id5 = c(0L, 0L, 1L, 0L, 1L)), .Names = c("date", "Id1", "Id2", 
    "id3", "id4", "id5"), class = "data.frame", row.names = c(NA, 
     -5L))
    

    【讨论】:

      【解决方案3】:

      这是另一个略有不同的tidyverse 选项:

      library(tidyverse)
      df %>% 
        gather(id, value, Id1:id5) %>% 
        filter(value != 0) %>% 
        mutate(row = str_replace(date, 'row', '')) %>% 
        select(id, row) %>% 
        group_by(id) %>% 
        mutate(occ = row_number()) %>% 
        spread(id, row)
      
      # A tibble: 3 x 6
          occ Id1   Id2   id3   id4   id5  
        <int> <chr> <chr> <chr> <chr> <chr>
      1     1 1     3     2     1     3    
      2     2 4     4     5     2     5    
      3     3 NA    NA    NA    5     NA 
      
      
      #sample data:
      
      df <- read.table(text='date Id1 Id2 id3 id4 id5
                       row1  1   0   0   1   0
                       row2  0   0   1   1   0
                       row3  0   1   0   0   1
                       row4  1   1   0   0   0
                       row5  0   0   1   1   1', header = TRUE)
      

      【讨论】:

      • @sbha- 运行此程序时收到以下响应(我已将 DF 更改为实际数据帧名称),并且不确定如何解决它/错误来自何处:错误[.data.frame(order_piv_cast, , c(.(occ = 1:N), lapply(.SD, : 未使用的参数 (.SDcols = -"Date")
      • 我不熟悉那个错误。看起来它来自不同的函数调用。您是否能够使用示例数据框重现答案中的输出?真实数据框是否可能具有不同的列名或不同的格式?大写很重要——“日期”与“日期”会引发错误。
      • 抱歉,我忽略了转换为 data.table。这工作得很好谢谢!
      【解决方案4】:

      这是一种不同的方法,无需来回重塑。

      它使用which() 函数获取行号并单独折叠每一列:

      # get maximum number of rows after collapsing
      N <- DT[, Reduce(pmax, lapply(.SD, function(x) sum(x == 1))), .SDcols = -"date"]
      DT[, c(.(occ = 1:N), lapply(.SD, function(x) {
        tmp <- which(x == 1)
        c(tmp, rep("", N - length(tmp)))
      })), .SDcols = -"date"]
      
         occ Id1 Id2 id3 id4 id5
      1:   1   1   3   2   1   3
      2:   2   4   4   5   2   5
      3:   3               5
      

      数据

      library(data.table)
      DT <- fread(
        "date Id1 Id2 id3 id4 id5
      row1  1   0   0   1   0
      row2  0   0   1   1   0
      row3  0   1   0   0   1
      row4  1   1   0   0   0
      row5  0   0   1   1   1  "
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-05
        • 1970-01-01
        • 2020-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-29
        相关资源
        最近更新 更多