从R中的数据帧每2列排列一个

时间:2017-07-05 05:55:27

标签: r

嗨,我有一个df,如下所示,显示日期及其受尊重的

date   1_val   date  2_val  . . . .  date  n_val  
  2014   23      2014  33    . . . .  2014   34
  2015   22      2016  12    . . . .  2016   99

我尝试使用硬编码将列排列在另一个

之下
for 1&2 columns
a=1
b=2
names_2<-df[,c(a,b)]
colnames(names_2)[1]<-"Date"
names_2 <- names_2[!apply(is.na(names_2) | names_2 == "", 1, all),]
names_2<-melt(names_2,id=colnames(names_2)[1])
samp_out<-names_2

for 3&4 columns
a=3
b=4
names_2<-df[,c(a,b)]
colnames(names_2)[1]<-"Date"
names_2 <- names_2[!apply(is.na(names_2) | names_2 == "", 1, all),]
names_2<-melt(names_2,id=colnames(names_2)[1])
samp_out1<-names_2 

till n-numbers
df1= rbind(samp_out,samp_out1,......samp_out_n)

输出

 date   variable   value
2014     1_val       23
2015     1_val       22
2014     2_val       33
2016     2_val       12
.
.
2014     n_val      34
2016     n_val      99

提前致谢

3 个答案:

答案 0 :(得分:1)

melt中的函数data.table执行此操作:

melt(df, id = "Date", measure = patterns("_val"))

您可以指定要转动的变量的名称(在本例中为Date)以及要保留值的变量中的模式。您也可以提供包含所有变量名的向量。

> DT <- data.table(Date = c(2014,2013), `1_val` = c(33, 32), Date = c(2014, 2013), `2_val` = c(65, 34))
> DT
   Date 1_val Date 2_val
1: 2014    33 2014    65
2: 2013    32 2013    34
> melt(DT, id = "Date", measure = patterns("_val"))
   Date variable value
1: 2014    1_val    33
2: 2013    1_val    32
3: 2014    2_val    65
4: 2013    2_val    34

答案 1 :(得分:1)

您可以使用基础R中的stack

setNames(data.frame(stack(df[c(TRUE, FALSE)])[1], 
                    stack(df[c(FALSE, TRUE)])), 
       c('date', 'value', 'variable'))

#  date value variable
#1 2014    33    1_val
#2 2013    32    1_val
#3 2014    65    2_val
#4 2013    34    2_val

答案 2 :(得分:0)

定义不整洁的矩形

library(magrittr)
csv <- "date,1_val,date,2_val,date,3_val  
  2014,23,2014,33,2014,34
  2015,22,2016,12,2016,99" 

读入数据框,然后转换为长/ eav矩形。

ds_eav <- csv %>%   
  readr::read_csv() %>% 
  tibble::rownames_to_column(var="height") %>% 
  tidyr::gather(key=key, value=value, -height)

输出

# A tibble: 12 x 4
     key index value height
   <chr> <int> <int>  <int>
 1  date     1  2014      1
 2  date     1  2015      2
 3 value     1    23      1
 4 value     1    22      2
 5  date     2  2014      1
 6  date     2  2016      2
 7 value     2    33      1
 8 value     2    12      2
 9  date     3  2014      1
10  date     3  2016      2
11 value     3    34      1
12 value     3    99      2

确定哪些行是日期/值。然后将日期的索引向上移动1。

ds_eav <- ds_eav %>% 
  dplyr::mutate(
    index_val  = sub("^(\\d+)_val$" , "\\1", key),
    index_date = sub("^date_(\\d+)$", "\\1", key),
    index_date = dplyr::if_else(key=="date", "0", index_date),
    key        = dplyr::if_else(grepl("^date(_\\d+)*", key), "date", "value"),
    index      = dplyr::if_else(key=="date", index_date, index_val),
    index      = as.integer(index),
    index      = index + dplyr::if_else(key=="date", 1L, 0L)
  ) %>% 
  dplyr::select(key, index, value, height)

遵循@ jarko-dubbeldam的建议,并在最后一步使用spread / gather

ds_eav %>% 
  tidyr::spread(key=key, value=value)

输出

# A tibble: 6 x 4
  index height  date value
* <int>  <int> <int> <int>
1     1      1  2014    23
2     1      2  2015    22
3     2      1  2014    33
4     2      2  2016    12
5     3      1  2014    34
6     3      2  2016    99

您可以使用paste0(index, "_val")来获得准确的输出。但我更喜欢将它们保留为整数,因此您可以在必要时对它们进行数学运算(例如max())。

编辑1 :整合建议&amp; @ jarko-dubbeldam和@hnskd的更正。 编辑2 :如果输入不是平衡矩形,则使用rownames_to_column()(例如,一列不是所有行)。