R中的左移列

时间:2017-11-25 09:02:33

标签: r dataframe data.table

我有这样的数据集

temp <- structure(list(col_1 = c("", "P9603", "", "", "11040", 
"80053"), col_2 = c("84484", "80061", "", "80061", "A0428", "85025"
), col_3 = c("V2632", "82310", "", "", "", "86357"), col_4 = c("J1170", 
"84305", "62311", "80061", "", ""), col_5 = c("", "86708", "J0690", 
"", "", "")), .Names = c("col_1", "col_2", "col_3", "col_4", 
"col_5"), class = c("data.table", "data.frame"))

   col_1 col_2 col_3 col_4 col_5
1:       84484 V2632 J1170      
2: P9603 80061 82310 84305 86708
3:                   62311 J0690
4:       80061       80061                        
5: 11040 A0428                  
6: 80053 85025 86357 

是否有可能像这样移动列

   col_1 col_2 col_3 col_4 col_5
1: 84484 V2632 J1170              #LEFT SHIFT 1
2: P9603 80061 82310 84305 86708  #NO CHANGE
3: 62311 J0690                    #LEFT SHIFT 3
4: 80061 80061                    #LEFT SHIFT 1 FOR FIRST ITEM, 
                                  #LEFT SHIFT 2 FOR 2ND ITEM 
5: 11040 A0428                    #NO CHANGE
6: 80053 85025 86357              #NO CHANGE

如果左侧的值为空,我正在向左移动列

2 个答案:

答案 0 :(得分:2)

以下是使用data.table的选项。按行序列unlist分组,数据。(.SD),order的子集由逻辑向量(un=='')分组,转换为list然后在删除&#39; grp&#39;之后用原始列名设置名称。柱

setnames(temp[, {un <- unlist(.SD); as.list(un[order(un=='')])},
    .(grp = 1:nrow(temp))][, grp := NULL], names(temp))[]
#  col_1 col_2 col_3 col_4 col_5
#1: 84484 V2632 J1170            
#2: P9603 80061 82310 84305 86708
#3: 62311 J0690                  
#4: 80061 80061                  
#5: 11040 A0428                  
#6: 80053 85025 86357       

或者另一个选项是在创建序列列后将melt转换为长格式,然后dcast将其格式化为宽格式

dcast(melt(temp[, n := seq_len(.N)], id.var = 'n')[order(n, value == ''),
     .(value, variable = names(temp)[1:5]), n], n ~ variable)[, n := NULL][]

答案 1 :(得分:1)

可能有更优雅的方式,但这有效:

library(plyr)

x = apply(temp,1,function(x) {t(as.matrix(unname(x[nchar(x)>0])))})
x = do.call(rbind.fill.matrix, x)
x[is.na(x)]=''
colnames(x) = colnames(temp)[1:ncol(x)]
x = as.data.frame(x)

输出:

  col_1 col_2 col_3 col_4 col_5
1 84484 V2632 J1170            
2 P9603 80061 82310 84305 86708
3 62311 J0690                  
4 80061 80061                  
5 11040 A0428                  
6 80053 85025 86357

基本上,使用nchar(x)>0查找每行的所有条目,并使用rbind.fill.matrix对它们进行行绑定,因此它们是左对齐的。然后将NA替换为'',将列名替换为原始列名(考虑到剩下的列数可能较少),并转换为数据帧。

希望这有帮助!