我想整理一些在前两行中用两个列标题设置的数据:
第一行(标题):实际上是度量的类型(例如 估计值,标准错误,上限,下限)。
第二行(也是标题):是度量的年份。
我是否可以使用gather()
或其他任何方式整理数据?
此外,当重复测量时(例如Rank,Rank.1),它实际上应该仅读取Rank,并且仅因Year而不同。有什么办法可以解决这个问题?
Country_Territory WBCode Estimate StdErr NumSrc Rank Lower
1 Year <NA> 1996.00 1996.00 1996 1996.00 1996.00
2 Andorra ADO 1.32 0.48 1 87.10 72.04
3 Afghanistan AFG -1.29 0.34 2 4.30 0.00
4 Angola AGO -1.17 0.26 4 9.68 0.54
Upper Estimate.1 StdErr.1 NumSrc.1 Rank.1 Lower.1 Upper.1
1 1996.00 1998.00 1998.00 1998 1998.00 1998.00 1998.00
2 96.77 1.38 0.46 1 89.18 74.74 96.91
3 27.42 -1.18 0.33 2 9.79 0.00 31.44
4 27.42 -1.41 0.21 6 1.55 0.00 13.40
这是输入我的数据样本的代码:
df <- data.frame(stringsAsFactors=FALSE,
Country_Territory = c("Year", "Andorra", "Afghanistan", "Angola"),
WBCode = c(NA, "ADO", "AFG", "AGO"),
Estimate = c(1996, 1.32, -1.29, -1.17),
StdErr = c(1996, 0.48, 0.34, 0.26),
NumSrc = c(1996, 1, 2, 4),
Rank = c(1996, 87.1, 4.3, 9.68),
Lower = c(1996, 72.04, 0, 0.54),
Upper = c(1996, 96.77, 27.42, 27.42),
Estimate = c(1998, 1.38, -1.18, -1.41),
StdErr = c(1998, 0.46, 0.33, 0.21),
NumSrc = c(1998, 1, 2, 6),
Rank = c(1998, 89.18, 9.79, 1.55),
Lower = c(1998, 74.74, 0, 0),
Upper = c(1998, 96.91, 31.44, 13.4)
)
例如,此尝试:
df %>% gather(key = measure, value = number, 3:14)
没有完全满足我的需求
Country_Territory WBCode measure number
1 Year <NA> Estimate 1996.00
2 Andorra ADO Estimate 1.32
3 Afghanistan AFG Estimate -1.29
4 Angola AGO Estimate -1.17
5 Year <NA> StdErr 1996.00
6 Andorra ADO StdErr 0.48
因为年份与Country_Territory混合在一起。
答案 0 :(得分:2)
这是一个选择:
library(tidyverse)
# get unique Year values and create column names (to add later)
df %>%
filter(Country_Territory == "Year") %>%
gather() %>%
filter(value != "Year" & !is.na(value)) %>%
pull(value) %>%
unique() %>%
paste0("Year_",.) -> col_years
# reshape data (excluding the Year row)
df %>%
filter(Country_Territory != "Year") %>%
gather(key,y,-Country_Territory, -WBCode) %>%
separate(key, c("measure","v")) %>%
group_by(v = ifelse(is.na(v), 0, v)) %>%
nest() -> df_info
reduce(df_info$data, function(x,y) left_join(x,y,by=c("Country_Territory","WBCode","measure"))) %>%
setNames(c("Country_Territory", "WBCode", "measure", col_years))
# # A tibble: 18 x 5
# Country_Territory WBCode measure Year_1996 Year_1998
# <chr> <chr> <chr> <dbl> <dbl>
# 1 Andorra ADO Estimate 1.32 1.38
# 2 Afghanistan AFG Estimate -1.29 -1.18
# 3 Angola AGO Estimate -1.17 -1.41
# 4 Andorra ADO StdErr 0.48 0.46
# 5 Afghanistan AFG StdErr 0.34 0.33
# 6 Angola AGO StdErr 0.26 0.21
# 7 Andorra ADO NumSrc 1 1
# 8 Afghanistan AFG NumSrc 2 2
# 9 Angola AGO NumSrc 4 6
# 10 Andorra ADO Rank 87.1 89.2
# 11 Afghanistan AFG Rank 4.3 9.79
# 12 Angola AGO Rank 9.68 1.55
# 13 Andorra ADO Lower 72.0 74.7
# 14 Afghanistan AFG Lower 0 0
# 15 Angola AGO Lower 0.54 0
# 16 Andorra ADO Upper 96.8 96.9
# 17 Afghanistan AFG Upper 27.4 31.4
# 18 Angola AGO Upper 27.4 13.4
如果将以上输出另存为df_upd
,则可以重新整形以使Year
作为一列:
df_upd %>%
gather(Year, value, -Country_Territory, -WBCode, -measure) %>%
separate(Year, c("y","Year"), convert = T) %>%
select(-y)
# # A tibble: 36 x 5
# Country_Territory WBCode measure Year value
# <chr> <chr> <chr> <int> <dbl>
# 1 Andorra ADO Estimate 1996 1.32
# 2 Afghanistan AFG Estimate 1996 -1.29
# 3 Angola AGO Estimate 1996 -1.17
# 4 Andorra ADO StdErr 1996 0.48
# 5 Afghanistan AFG StdErr 1996 0.34
# 6 Angola AGO StdErr 1996 0.26
# 7 Andorra ADO NumSrc 1996 1
# 8 Afghanistan AFG NumSrc 1996 2
# 9 Angola AGO NumSrc 1996 4
# 10 Andorra ADO Rank 1996 87.1
# # ... with 26 more rows
答案 1 :(得分:1)
也许(如果您只有两种措施):
bind_rows(df %>% select(1:2,3:8) %>%
mutate(Year=first(Estimate)),
df %>% select(1:2,9:14) %>%
rename_all(funs(str_replace(.,"\\.1",""))) %>%
mutate(Year=first(Estimate))) %>%
filter(Country_Territory!="Year")
# Country_Territory WBCode Estimate StdErr NumSrc Rank Lower Upper Year
#1 Andorra ADO 1.32 0.48 1 87.10 72.04 96.77 1996
#2 Afghanistan AFG -1.29 0.34 2 4.30 0.00 27.42 1996
#3 Angola AGO -1.17 0.26 4 9.68 0.54 27.42 1996
#4 Andorra ADO 1.38 0.46 1 89.18 74.74 96.91 1998
#5 Afghanistan AFG -1.18 0.33 2 9.79 0.00 31.44 1998
#6 Angola AGO -1.41 0.21 6 1.55 0.00 13.40 1998
答案 2 :(得分:1)
Data.table解决方案。
需要一些准备工作(设置名字并创建唯一名称表),但是速度很快。
解决方案也可以使用两年以上。
library( data.table )
dt <- as.data.table( df ) #or use setDT( df )
#extract unique years from the first row from the thirs column untill end of dt
dt.years <- as.data.table ( unique( t( (dt[1, 3:ncol(dt)]) ) ) )
dt.years[, year_id := 1:.N ]
setnames(dt.years, c("year", "year_id" ) )
#melt row 2:n of the data.table
dt.melt <- melt( dt[2:nrow(dt)],
id.vars = c( "Country_Territory", "WBCode"),
measure = patterns( "Estimate", "StdErr", "NumSrc", "Rank", "Lower", "Upper"),
value.name = c( "Estimate", "StdErr", "NumSrc", "Rank", "Lower", "Upper" ),
variable.name = "year")
#left join both datatables
result <- dt.years[dt.melt, on = c( year_id = "year")]
#cleaning and renaming
result[, year_id := NULL]
结果
# year Country_Territory WBCode Estimate StdErr NumSrc Rank Lower Upper
# 1: 1996 Andorra ADO 1.32 0.48 1 87.10 72.04 96.77
# 2: 1996 Afghanistan AFG -1.29 0.34 2 4.30 0.00 27.42
# 3: 1996 Angola AGO -1.17 0.26 4 9.68 0.54 27.42
# 4: 1998 Andorra ADO 1.38 0.46 1 89.18 74.74 96.91
# 5: 1998 Afghanistan AFG -1.18 0.33 2 9.79 0.00 31.44
# 6: 1998 Angola AGO -1.41 0.21 6 1.55 0.00 13.40
答案 3 :(得分:1)
data.table
的{{1}}方法能够同时重塑多个度量列。无需使用melt()
函数来重命名列。
patterns()
library(data.table) # reshape multiple measure columns simultaneously from wide to long format cols <- c("Estimate", "StdErr", "NumSrc", "Rank", "Lower", "Upper") long <- melt(setDT(df), measure.vars = patterns(cols), value.name = cols) # extract years yrs <- long[Country_Territory == "Year", .(variable, Year = as.integer(Estimate))] # join to get a separate Year column, remove Year rows and helper column result <- yrs[long[Country_Territory != "Year"], on = "variable"][, variable := NULL][] result
整形后, Year Country_Territory WBCode Estimate StdErr NumSrc Rank Lower Upper
1: 1996 Andorra ADO 1.32 0.48 1 87.10 72.04 96.77
2: 1996 Afghanistan AFG -1.29 0.34 2 4.30 0.00 27.42
3: 1996 Angola AGO -1.17 0.26 4 9.68 0.54 27.42
4: 1998 Andorra ADO 1.38 0.46 1 89.18 74.74 96.91
5: 1998 Afghanistan AFG -1.18 0.33 2 9.79 0.00 31.44
6: 1998 Angola AGO -1.41 0.21 6 1.55 0.00 13.40
列表示以宽格式属于一列子集的行,即属于某一特定年份的行。