重塑组内的数据 - 单行中的组

时间:2018-01-30 09:11:42

标签: r dplyr reshape2

这是我的输入数据:

 DeviceID   ContentID   Use
 D1 C1  0.678491346
 D1 C2  0.302147374
 D2 C1  0.695790066
 D2 C2  0.645849165
 D3 C1  0.83503997
 D3 C2  0.3622916

预期产出:

DeviceID    ContentID_1 Use_1   ContentID_2 Use_2
D1  C1  0.678491346 C2  0.302147374
D2  C1  0.695790066 C2  0.645849165
D3  C1  0.83503997  C2  0.3622916

我尝试使用reshape2重塑它,但无法以所需的格式获取它。

我试过了:

 df %>% 
   group_by(DeviceID) %>% 
   mutate(rn = paste0("Content",row_number())) %>% 
   spread(rn, Use)

dcast(df,
      DeviceID~ContentID,
      value.var ="Use")

任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:2)

我们可以使用aggregatedata.frame(Reduce(cbind,aggregate(.~Device,dat,I)))[c(1,2,4,3,5)] init V2 V4 V3 V5 1 D1 C1 0.678491346 C2 0.302147374 2 D2 C1 0.695790066 C2 0.645849165 3 D3 C1 0.83503997 C2 0.3622916 以上面给出的格式重新排列

 map2_dfc(s<-dat%>%spread(Id,Content),names(s),~rev(stack(s,.y)))
     ind values ind1   values1 ind2   values2
1 Device     D1   C1 0.6784913   C2 0.3021474
2 Device     D2   C1 0.6957901   C2 0.6458492
3 Device     D3   C1 0.8350400   C2 0.3622916

这是图书馆dplyr的蛮力

var x = setInterval(
  (startValue => () => {
    console.log(startValue--);
  })(100),
  1000
);

答案 1 :(得分:2)

发布我的解决方案:

exoplayer:2.6.1

在评论中包括@AntoniosK的建议。

答案 2 :(得分:2)

从v1.9.6开始(2015年9月19日CRAN),data.table可以同时投放多个值列:

library(data.table)
dcast(setDT(df), DeviceID ~ rowid(DeviceID), value.var = c("ContentID", "Use"))
    DeviceID  ContentID_1  ContentID_2     Use_1     Use_2
1:        D1           C1           C2 0.6784913 0.3021474
2:        D2           C1           C2 0.6957901 0.6458492
3:        D3           C1           C2 0.8350400 0.3622916

更改列顺序

结果包含预期的列,但顺序不同。 dcast()创建按value.var分组的新列。

OP尚未表明确切的列顺序是否重要。但是,通过按引用更改列顺序,即不使用setcolorder()复制整个数据对象,可以准确地再现预期结果:

cols <- c("ContentID", "Use")
wide <- dcast(setDT(df), DeviceID ~ rowid(DeviceID), value.var = cols)
new_col_order <- CJ(seq_len(uniqueN(df$ContentID)), cols)[, paste(V2, V1, sep = "_")]
setcolorder(wide, new_col_order)
wide
   ContentID_1     Use_1 ContentID_2     Use_2 DeviceID
1:          C1 0.6784913          C2 0.3021474       D1
2:          C1 0.6957901          C2 0.6458492       D2
3:          C1 0.8350400          C2 0.3622916       D3

CJ()是行ID与value.vars的交叉连接,以按所需顺序创建列名。

我已提交feature request on GitHub,可选择更改dcast()中的列顺序。

数据

library(data.table)
df <- fread(
  " DeviceID  ContentID  Use
 D1 C1  0.678491346
  D1 C2  0.302147374
  D2 C1  0.695790066
  D2 C2  0.645849165
  D3 C1  0.83503997
  D3 C2  0.3622916"
)

答案 3 :(得分:1)

df = read.table(text = "
DeviceId  ContentID  Use
D1 C1  0.678491346
D1 C2  0.302147374
D2 C1  0.695790066
D2 C2  0.645849165
D3 C1  0.83503997
D3 C2  0.3622916
", header=T, stringsAsFactors=F)

library(tidyverse)

df %>%
  group_by(DeviceId) %>%
  summarise_all(function(x) paste0(x, collapse = "_")) %>%
  separate(ContentID, c("ID_1","ID_2"), sep="_") %>%
  separate(Use, c("Use_1","Use_2"), sep="_")

# # A tibble: 3 x 5
#   DeviceId ID_1  ID_2  Use_1       Use_2      
# * <chr>    <chr> <chr> <chr>       <chr>      
# 1 D1       C1    C2    0.678491346 0.302147374
# 2 D2       C1    C2    0.695790066 0.645849165
# 3 D3       C1    C2    0.83503997  0.3622916 

答案 4 :(得分:1)

library(data.table)
DT <- setDT(df)

使用你的dcast意图,你可以做到

    Reduce(function(dtf1,dtf2) merge(dtf1,dtf2, by = "DeviceId"), 
           lapply( unique(DT$ContentID),
                   function(x){dcast(DT[ContentID == x],DeviceId + ContentID  ~ ContentID ,value.var = "Use")} ))

   DeviceId ContentID.x        C1 ContentID.y        C2
1:       D1          C1 0.6784913          C2 0.3021474
2:       D2          C1 0.6957901          C2 0.6458492
3:       D3          C1 0.8350400          C2 0.3622916