【问题标题】:R move columns to be rows of other columnsR将列移动到其他列的行
【发布时间】:2021-10-20 11:16:34
【问题描述】:

我正在将凌乱的 Excel 工作表转换为可用数据。基本结构是重复的变量块,行中具有相似的项目。我想移动列,使它们成为第一个列块的行。

很难描述所以这里是mwe。

d1 = structure(list(...1 = c("p", "w", "s", NA, "A Ex", NA, "Pres", 
"Time", "HR"), ...2 = c("1", "1", "1", NA, "Walk", NA, NA, NA, 
NA), ...3 = c(NA, NA, NA, NA, NA, NA, "Done", "Time", "HR"), 
    ...4 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA), ...5 = c("p", 
    "w", "s", NA, "A Ex", NA, "Pres", "Time", "HR"), ...6 = c("1", 
    "1", "2", NA, "Walk", NA, NA, NA, NA), ...7 = c(NA, NA, NA, 
    NA, NA, NA, "Done", "Time", "HR"), ...8 = c(NA, NA, NA, NA, 
    NA, NA, NA, NA, NA), ...9 = c("p", "w", "s", NA, "A Ex", 
    NA, "Pres", "Time", "HR"), ...10 = c("1", "1", "3", NA, "Walk", 
    NA, NA, NA, NA), ...11 = c(NA, NA, NA, NA, NA, NA, "Done", 
    "Time", "HR"), ...12 = c(NA, NA, NA, NA, NA, NA, NA, NA, 
    NA)), row.names = c(NA, -9L), class = c("tbl_df", "tbl", 
"data.frame"))

我想移动 5:8 和 6:12 列,使它们成为 1:4 的附加行,因此结果是:

df2 = structure(list(...1 = c("p", "w", "s", NA, "A Ex", NA, "Pres", 
"Time", "HR", "p", "w", "s", NA, "A Ex", NA, "Pres", "Time", 
"HR", "p", "w", "s", NA, "A Ex", NA, "Pres", "Time", "HR"), ...2 = c("1", 
"1", "1", NA, "Walk", NA, NA, NA, NA, "1", "1", "2", NA, "Walk", 
NA, NA, NA, NA, "1", "1", "3", NA, "Walk", NA, NA, NA, NA), ...3 = c(NA, 
NA, NA, NA, NA, NA, "Done", "Time", "HR", NA, NA, NA, NA, NA, 
NA, "Done", "Time", "HR", NA, NA, NA, NA, NA, NA, "Done", "Time", 
"HR"), ...4 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, 
-27L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

    标签: r row columnsorting


    【解决方案1】:

    基础 R

    基本前提是按4列分组:

    splitframes <- split.default(d1, (seq_along(d1)-1) %/% 4)
    splitframes
    # $`0`
    # # A tibble: 9 x 4
    #   ...1  ...2  ...3  ...4 
    #   <chr> <chr> <chr> <lgl>
    # 1 p     1     <NA>  NA   
    # 2 w     1     <NA>  NA   
    # 3 s     1     <NA>  NA   
    # 4 <NA>  <NA>  <NA>  NA   
    # 5 A Ex  Walk  <NA>  NA   
    # 6 <NA>  <NA>  <NA>  NA   
    # 7 Pres  <NA>  Done  NA   
    # 8 Time  <NA>  Time  NA   
    # 9 HR    <NA>  HR    NA   
    # $`1`
    # # A tibble: 9 x 4
    #   ...1  ...2  ...3  ...4 
    #   <chr> <chr> <chr> <lgl>
    # 1 p     1     <NA>  NA   
    # 2 w     1     <NA>  NA
    

    不幸的是,rbind.data.frame 需要所有参数具有相同的名称,

    lapply(splitframes, names)
    # $`0`
    # [1] "...1" "...2" "...3" "...4"
    # $`1`
    # [1] "...5" "...6" "...7" "...8"
    # $`2`
    # [1] "...9"  "...10" "...11" "...12"
    

    所以我们需要先解决这个问题:

    splitframes <- lapply(splitframes, `colnames<-`, names(splitframes[[1]]))
    do.call(rbind, splitframes)
    # # A tibble: 27 x 4
    #    ...1  ...2  ...3  ...4 
    #  * <chr> <chr> <chr> <lgl>
    #  1 p     1     <NA>  NA   
    #  2 w     1     <NA>  NA   
    #  3 s     1     <NA>  NA   
    #  4 <NA>  <NA>  <NA>  NA   
    #  5 A Ex  Walk  <NA>  NA   
    #  6 <NA>  <NA>  <NA>  NA   
    #  7 Pres  <NA>  Done  NA   
    #  8 Time  <NA>  Time  NA   
    #  9 HR    <NA>  HR    NA   
    # 10 p     1     <NA>  NA   
    # # ... with 17 more rows
    

    dplyr

    这个包稍微宽松一点:

    splitframes <- split.default(d1, (seq_along(d1)-1) %/% 4)
    dplyr::bind_rows(splitframes)
    # New names:
    # * ...5 -> ...1
    # * ...6 -> ...2
    # * ...7 -> ...3
    # * ...8 -> ...4
    # New names:
    # * ...9 -> ...1
    # * ...10 -> ...2
    # * ...11 -> ...3
    # * ...12 -> ...4
    # # A tibble: 27 x 4
    #    ...1  ...2  ...3  ...4 
    #    <chr> <chr> <chr> <lgl>
    #  1 p     1     <NA>  NA   
    #  2 w     1     <NA>  NA   
    #  3 s     1     <NA>  NA   
    #  4 <NA>  <NA>  <NA>  NA   
    #  5 A Ex  Walk  <NA>  NA   
    #  6 <NA>  <NA>  <NA>  NA   
    #  7 Pres  <NA>  Done  NA   
    #  8 Time  <NA>  Time  NA   
    #  9 HR    <NA>  HR    NA   
    # 10 p     1     <NA>  NA   
    # # ... with 17 more rows
    

    数据表

    splitframes <- split.default(d1, (seq_along(d1)-1) %/% 4)
    library(data.table)
    rbindlist(splitframes)
    # Column 1 ['...5'] of item 2 is missing in item 1. Use fill=TRUE to fill with NA (NULL for list columns), or use.names=FALSE to ignore column names. use.names='check' (default from v1.12.2) emits this message and proceeds as if use.names=FALSE for  backwards compatibility. See news item 5 in v1.12.2 for options to control this message.
    #       ...1   ...2   ...3   ...4
    #     <char> <char> <char> <lgcl>
    #  1:      p      1   <NA>     NA
    #  2:      w      1   <NA>     NA
    #  3:      s      1   <NA>     NA
    #  4:   <NA>   <NA>   <NA>     NA
    

    要使该消息静音,请改用rbindlist(..., use.names=FALSE)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 2020-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多