按组重塑数据框

时间:2019-10-30 18:58:45

标签: r

我有一个数据帧,其中每个观察值都是一个大案例,每20行有一个新案例开始,即行1:20是案例1,而21:40是案例2。我想整体分析每个案例,所以我想基于变量CaseId重塑数据,以便每个案例在一次观察中表示,而不会丢失任何数据。我尝试了这段代码。

train_clean <- train %>%
  group_by(CaseId) %>%
  summarise_all(function(train) paste0(train, collapse = "_")) %>%
  cSplit(names(.)[-1], '_')

这是部分有效的方法,其中每种情况都在单行中表示,但是创建的情况恰好是每一行的列数加倍,因此,代替了具有X1 ... X20的变量X,其中表示了来自原始数据的每个观察值在这种情况下,单行显示X1到x40,但X21:X40为空。这发生在数据中的每个变量上,我需要在代码中进行一些调整以使其按我希望的方式工作。

这是我想做的一个基本示例,但规模更大。

       X         CaseID
1  73.91 20170907000118
2  74.67 20170907000118
3  71.07 20170907000139
4  66.46 20170907000139
           CaseID    X1    X2
1  20170907000118 73.91 74.67
2  20170907000139 71.07 66.46

感谢您能提供的任何帮助,谢谢

3 个答案:

答案 0 :(得分:1)

根据您的示例数据,这是一个data.table解决方案

library(data.table)
#read in sample data
DT <- fread("X         CaseID
73.91 20170907000118
74.67 20170907000118
71.07 20170907000139
66.46 20170907000139")
#create rownubers by CaseID-group
DT[, id := rowid( CaseID )]
#cast to desired wide format
dcast( DT, CaseID ~ paste0("X", id), value.var = "X")

#            CaseID    X1    X2
# 1: 20170907000118 73.91 74.67
# 2: 20170907000139 71.07 66.46

答案 1 :(得分:0)

在创建按“ CaseID”分组的序列列之后,我们可以使用pivot_wider中的tidyr

library(tidyr)
library(dplyr)
library(stringr)
df1 %>%  
  group_by(CaseID = as.character(CaseID)) %>%
  mutate(rn = str_c("X", row_number())) %>% 
  ungroup %>% 
  pivot_wider(names_from = rn, values_from = X)
# A tibble: 2 x 3
#  CaseID            X1    X2
#  <chr>          <dbl> <dbl>
#1 20170907000118  73.9  74.7
#2 20170907000139  71.1  66.5

数据

df1 <- structure(list(X = c(73.91, 74.67, 71.07, 66.46), CaseID = c(20170907000118, 
20170907000118, 20170907000139, 20170907000139)), 
     class = "data.frame", row.names = c("1", 
"2", "3", "4"))

答案 2 :(得分:0)

尝试使用以下内容:

library(tidyr)
train_clean <- train %>%
     spread(key= caseID, value  = X)

只要在所有单独的情况下X观测值对称,该方法就可以按您的意愿工作。

编辑:如果确实缺少值,则可以设置fill =NA或任何其他值以占据在其他情况只有一个的情况下该情况下没有其他X的列。