【问题标题】:Altering rows and columns of the dataframe更改数据框的行和列
【发布时间】:2014-04-06 07:17:42
【问题描述】:

我想更改data.framerowscolumns 的顺序。我使用了transpose,但它没有按预期工作。我是 plyr 包中的 apply/ddply 的新手。

这是输入。

Destination S1  S2  S3  S4
Section_A   NA  NA  NA  NA
County1     94  82  121 148
County2     95  87  127 159
County3     96  98  139 182
County4     102 95  142 182
Section_B   NA  NA  NA  NA
County5     120 122 187 254
County6     119 121 185 251
County7     119 121 185 251
County8     114 116 175 236
County9     109 111 165 221
County10    110 112 167 224
Section_C   NA  NA  NA  NA
County11    47  41  33  19
County12    43  36  24  5
County13    143 191 279 415
County14    144 126 215 286
County15    142 135 222 302

我期待这样的事情:

            Destination S1  S2  S3  S4
Section_A   County1     94  82  121 148
Section_A   County2     95  87  127 159
Section_A   County3     96  98  139 182
Section_A   County4     102 95  142 182
Section_B   County5     120 122 187 254
Section_B   County6     119 121 185 251
Section_B   County7     119 121 185 251
Section_B   County8     114 116 175 236
Section_B   County9     109 111 165 221
Section_B   County10    110 112 167 224
Section_C   County11    47  41  33  19
Section_C   County12    43  36  24  5
Section_C   County13    143 191 279 415
Section_C   County14    144 126 215 286
Section_C   County15    142 135 222 302

有人可以调查一下并帮助我吗?

提前致谢。

【问题讨论】:

    标签: r csv dataframe


    【解决方案1】:

    也许你可以试试这样的:

    out <- lapply(split(mydf, cumsum(apply(is.na(mydf[2:5]), 1, all))), 
                  function(x) {
                    x$Section <- x[1, 1]
                    x[-1, c("Section", "Destination", paste0("S", 1:4))]
                  })
    do.call(rbind, out)
    #        Section Destination  S1  S2  S3  S4
    # 1.2  Section_A     County1  94  82 121 148
    # 1.3  Section_A     County2  95  87 127 159
    # 1.4  Section_A     County3  96  98 139 182
    # 1.5  Section_A     County4 102  95 142 182
    # 2.7  Section_B     County5 120 122 187 254
    # 2.8  Section_B     County6 119 121 185 251
    # 2.9  Section_B     County7 119 121 185 251
    # 2.10 Section_B     County8 114 116 175 236
    # 2.11 Section_B     County9 109 111 165 221
    # 2.12 Section_B    County10 110 112 167 224
    # 3.14 Section_C    County11  47  41  33  19
    # 3.15 Section_C    County12  43  36  24   5
    # 3.16 Section_C    County13 143 191 279 415
    # 3.17 Section_C    County14 144 126 215 286
    # 3.18 Section_C    County15 142 135 222 302
    

    基本思想是找到新“部分”的来源(我认为这是“S1”到“S4”列有一行NA值的位置)并使用它来修改原始数据.


    这是上面代码的注释版本:

    out <- lapply(
      ## First, we split the data...
      split( 
        mydf,
        ## ... by a grouping variable we create.
        ## I've made use of the NA rows to create
        ##   the groups.
        cumsum(apply(is.na(mydf[2:5]), 1, all))), 
      ## Next, we apply our function, which...
      function(x) {
        ## ... creates a column called "Section"
        ##   which contains the value from the
        ##   first column of the first row of
        ##   each split
        x$Section <- x[1, 1]
        ## ... and then deletes the first row entirely.
        ## The `c("Section", ...)` part just specifies
        ##    the column order we want to use in the end.
        x[-1, c("Section", "Destination", paste0("S", 1:4))]
    })
    
    ## The above results in a `list`.
    ## Put it back into a `data.frame` with:
    do.call(rbind, out)
    

    这是使用“zoo”包中的na.locf 的另一种方法:

    library(zoo) ## For na.locf
    mydf$Section <- as.character(mydf$Destination)
    mydf$Section[grep("Sect", mydf$Section, invert=TRUE)] <- NA
    mydf$Section <- na.locf(mydf$Section)
    mydf[complete.cases(mydf), ]
    

    【讨论】:

    • 感谢您的回复。请介意解释一下,function(x) { x$Section &lt;- x[1, 1] x[-1, c("Section", "Destination", paste0("S", 1:4))] })。如果section 的名称类似于A,B,C,D,这是否可行。提前感谢您的支持
    • @user3444971,请参阅我的答案的更新版本以获取答案的评论版本。只要每个新组由 S1 到 S4 列中的一行 NA 值标识,lapply 版本就应该工作。
    • 非常感谢您的帮助和解释。这对我很有效。再次感谢您
    【解决方案2】:

    1) 实际上,这可以在没有任何apply 家族的情况下完成。在这里,我们使用了 S1 对于 Section 行是 NA 的事实(但可能还有其他同样好的标准来选择 Section 行)。使用此标准,我们将g 定义为每行一个元素DF 的向量,这对于部分行为TRUE,对于所有其他行为FALSE。那么DF$Destination[g] 是唯一的节名,DF$Destination[g][cumsum(g)] 是一个向量,DF 的每行一个元素包含节名。最后,我们使用[!g,] 删除部分行。

    g <- is.na(DF$S1)
    cbind(Section = DF$Destination[g][cumsum(g)], DF)[!g, ]
    

    给予:

         Section Destination  S1  S2  S3  S4
    2  Section_A     County1  94  82 121 148
    3  Section_A     County2  95  87 127 159
    4  Section_A     County3  96  98 139 182
    5  Section_A     County4 102  95 142 182
    7  Section_B     County5 120 122 187 254
    8  Section_B     County6 119 121 185 251
    9  Section_B     County7 119 121 185 251
    10 Section_B     County8 114 116 175 236
    11 Section_B     County9 109 111 165 221
    12 Section_B    County10 110 112 167 224
    14 Section_C    County11  47  41  33  19
    15 Section_C    County12  43  36  24   5
    16 Section_C    County13 143 191 279 415
    17 Section_C    County14 144 126 215 286
    18 Section_C    County15 142 135 222 302
    

    2) 使用与上述相同的g 的另一种方法是使用ave 来形成截面向量:

    cbind(Section = ave(DF$Destination, cumsum(g), FUN = function(x) x[1]), DF)[!g, ]
    

    注意:我们使用此数据框进行测试。下次请使用dput 显示您的输入 像这样的可复制形式:

    DF <- structure(list(Destination = c("Section_A", "County1", "County2", 
    "County3", "County4", "Section_B", "County5", "County6", "County7", 
    "County8", "County9", "County10", "Section_C", "County11", "County12", 
    "County13", "County14", "County15"), S1 = c(NA, 94L, 95L, 96L, 
    102L, NA, 120L, 119L, 119L, 114L, 109L, 110L, NA, 47L, 43L, 143L, 
    144L, 142L), S2 = c(NA, 82L, 87L, 98L, 95L, NA, 122L, 121L, 121L, 
    116L, 111L, 112L, NA, 41L, 36L, 191L, 126L, 135L), S3 = c(NA, 
    121L, 127L, 139L, 142L, NA, 187L, 185L, 185L, 175L, 165L, 167L, 
    NA, 33L, 24L, 279L, 215L, 222L), S4 = c(NA, 148L, 159L, 182L, 
    182L, NA, 254L, 251L, 251L, 236L, 221L, 224L, NA, 19L, 5L, 415L, 
    286L, 302L)), .Names = c("Destination", "S1", "S2", "S3", "S4"
    ), class = "data.frame", row.names = c(NA, -18L))
    

    修订:小幅改进,扩展解释,第二种方法。添加了dput(DF) 输出。

    【讨论】:

    • 非常感谢@G.Grothendieck。这以其他方式帮助了我。
    猜你喜欢
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 2011-08-30
    • 2013-02-06
    • 2014-07-16
    • 1970-01-01
    • 2012-07-28
    相关资源
    最近更新 更多