虽然可以争论宽格式数据框是否最容易在后续步骤中使用,但此请求的棘手部分是国家名称可能包含多个单词。这意味着像 tidyr::separate() 和 sep = " " 这样更简单的解决方案是不可行的。
这是一个解决方案,它使用每个国家/地区的长度将最后 4 个字符提取到 Year 列中,并将最后一个空格之前的所有内容提取为国家/地区。
就此示例而言,v1 代表奇数年数据,v2 代表偶数年数据。
首先,我们将问题中的图形转换为可用数据,并为包含多个单词的国家/地区名称添加几行。
textData <- "v1,Country,v2
0.93181,Denmark 2007,NA
NA,Denmark 2008,5.519108
0.64285,Denmark 2009,NA
NA,Denmark 2010,4.93885
.55260,Denmark 2011,NA
NA,Denmark 2012,5.101908
0.13187,United Kingdom 2007,NA
NA,United Kingdom 2008,3.18781"
df <- read.csv(text = textData)
接下来,我们加载几个包,创建一个列来计算 Country 每一行中的字符数,并用它来分隔 Year 和 countryName。我们还删除了在此操作期间创建的中间列,并将结果保存到yearlyData。
library(dplyr)
library(stringr)
df %>%
mutate(countryLength = str_length(Country),
countryName = substr(Country,1,countryLength - 5),
Year = as.numeric(substr(Country,countryLength - 4,countryLength))) %>%
select(!c(Country,countryLength)) %>%
rename(Country = countryName) -> yearlyData
此时我们将偶数年的数据分离到另一个数据框中,删除 v1 变量,并从 Year 中减去 1,这样我们就可以将它与奇数年的数据合并。
yearlyData %>%
filter(Year %% 2 == 0) %>%
select(-v1) %>%
mutate( Year = Year - 1) -> evenYears
接下来,我们读取年度数据,filter()取出偶数年的行,通过full_join()合并到evenYears数据框,重命名几列并为偶数年生成一个新列。
yearlyData %>%
filter(Year %% 2 == 1) %>%
rename(OddYearValue = v1) %>%
select(-v2) %>%
full_join(.,evenYears,by = c("Year","Country")) %>%
rename(EvenYearValue = v2,
OddYear = Year) %>%
mutate(EvenYear = OddYear + 1)
...和输出:
OddYearValue Country OddYear EvenYearValue EvenYear
1 0.93181 Denmark 2007 5.519108 2008
2 0.64285 Denmark 2009 4.938850 2010
3 0.55260 Denmark 2011 5.101908 2012
4 0.13187 United Kingdom 2007 3.187810 2008
>
笔记:数据框中的每一列都应包含一个且仅包含一个变量的整洁数据规范资产,因此我们没有按照原始帖子中的要求将OddYear、EvenYear和Country组合到一个列中。