簡體   English   中英

R中的復雜數據重塑

[英]Complex data reshaping in R

我有一個3列的數據框(下面提取):

df <- data.frame(
  id = c(1,1,1,2,2,2),
  Year = c(2007, 2008, 2009, 2007, 2008, 2009),
  A = c(5, 2, 3, 7, 5, 6),
  B = c(10, 0, 50, 13, 17, 17) 
)
df  

我想要這個:

df_needed <- data.frame(
  id= c(1, 2),
  A_2007 = c(5, 7),
  B_2007 = c(10, 13),
  A_2008 = c(2, 5),
  B_2008 = c(0, 17),
  A_2009 = c(3, 6),
  B_2009 = c(50, 17)
)
df_needed

我熟悉reshapetidyR但我認為他們不能管理這種轉變。

有沒有正確的方法來做到這一點,或者我需要使用自定義功能?

編輯:此示例已經過編輯,以便改進最終數據集中包含多條記錄的示例。

嘗試

library(dplyr)
library(tidyr) 
gather(df, Var, Val, -Year) %>% 
        unite(YearVar, Var, Year)  %>% 
        mutate(indx=1) %>% 
        spread(YearVar, Val)%>%
        select(-indx)
 #  A_2007 A_2008 A_2009 B_2007 B_2008 B_2009
 #1      5      2      3     10      0     50

更新

對於編輯,您可以更改gather的變量

gather(df, Var, Val, A:B) %>% 
         unite(YearVar, Var, Year) %>% 
         spread(YearVar, Val)
#   id A_2007 A_2008 A_2009 B_2007 B_2008 B_2009
#1  1      5      2      3     10      0     50
#2  2      7      5      6     13     17     17

這是使用data.table v> = 1.9.5的可能解決方案

library(data.table)
dcast(setDT(df), . ~ Year, value.var = c("A", "B"))
#    . 2007_A 2008_A 2009_A 2007_B 2008_B 2009_B
# 1: .      5      2      3     10      0     50

編輯 :根據您的新數據集,只需將id添加到公式中即可

dcast(setDT(df), id ~ Year, value.var = c("A", "B"))
#    id 2007_A 2008_A 2009_A 2007_B 2008_B 2009_B
# 1:  1      5      2      3     10      0     50
# 2:  2      7      5      6     13     17     17

好的' base::reshape在這里工作得很好。 首先創建一個虛擬id變量。

df$id <- 1
reshape(df, v.names = c("A", "B"), timevar = "Year", idvar = "id", direction = "wide")
#   id A.2007 B.2007 A.2008 B.2008 A.2009 B.2009
# 1  1      5     10      2      0      3     50

為了節省一些打字,因為你指定timevaridvar ,你沒有提供v.names

reshape(df, timevar = "Year", idvar = "id", direction = "wide")

這也適用於編輯過的數據(恰好有“id”變量)。

#    id A_2007 B_2007 A_2008 B_2008 A_2009 B_2009
#  1  1      5     10      2      0      3     50
#  2  2      7     13      5     17      6     17

您也可以使用reshape2::recast

recast(df, id ~ variable + Year, id.var = 1:2)

base R另一個簡單選項:

df_needed <- matrix(as.vector(t(df[, -1])), ncol=nrow(df)*(ncol(df)-1))
colnames(df_needed) <- paste(rep(colnames(df)[-1], nrow(df)), rep(df[, 1], e=ncol(df)-1), sep="_")

df_needed
#      A_2007 B_2007 A_2008 B_2008 A_2009 B_2009
#[1,]      5     10      2      0      3     50

編輯數據

df_split <- split(df, df$Year)
df_split <- lapply(df_split, function(df){colnames(df)[-1] <- paste(colnames(df)[-1], unique(df$Year), sep="_"); df <- df[, -1]; return(df)})
df_needed <- do.call("cbind", df_split)
colnames(df_needed) <- sub("^\\d{4}\\.","",colnames(df_needed))
df_needed
#  A_2007 B_2007 A_2008 B_2008 A_2009 B_2009
#1      5     10      2      0      3     50
#4      7     13      5     17      6     17

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM