我是r的新手,在处理数据以进行分析时遇到了一些麻烦。如果有人可以帮助,我将不胜感激。
我的数据看起来像这样:
df<- data.frame("Reporter" = c("USA", "USA", "USA", "USA", "USA","USA"),
"Partner" = c( "EU", "EU","EU","EU", "EU","EU"),
"Product cat." = c("1", "11", "111", "122", "12", "2"),
"Year" = c(1970, 1970, 1970, 1970, 1970, 1970),
"trade value" = c( 100, 50, 25, 5, 40, 220), stringsAsFactors = FALSE)
我有多个国家/地区年度观察数据,其中包含有关贸易的贸易数据。向量乘积。 cat 表示要出口哪种商品。 产品的位数越多。 cat ,则贸易信息的分类就越多。例如产品猫。 111(例如苹果)和112(例如香蕉)是产品类别11(例如水果)的子产品类别。产品类别11是食品的子类别(产品类别1)。
要进行分析,我需要以尽可能细分的水平报告所有值-即,我需要所有数据都具有尽可能多的位数。
我的问题是,对于某些国家(地区)年的观察,我只报告了较高汇总水平的数据。例如,考虑以下产品目录cat。作为示例中的比较。
ls.prod.cat<- data.frame(
"Product cat." = c("1", "11", "111", "122", "12","121","122","2","21","22","211"),
stringsAsFactors = FALSE)
在该示例中,我以2位数级别(12)报告了数据,该数据可以以3位数级别(121,122)报告。 我想做的是找到一种方法来对仅在较高聚合级别(例如12)报告的所有数据进行个性化处理,并更改其产品类别。在末尾添加“ m”。 因此,在操纵产品猫之后。 12应该变成 12m 。
类似地,用于更高级别的聚集。 例如,当仅在产品目录的第一位报告数据时。我想要一个在产品目录末尾添加两个“ mm”的数据。以反映仅在聚合的第一级报告数据。例如,在我的df中,这意味着该数据具有乘积cat。 2应成为产品猫。 2mm
----更新---
总而言之,我正在寻找一种方法来自动区分以较高聚合级别排他报告数据的行,并且这些行会改变产品类别。名称加上相应的m号。仅对于仅具有较高聚合级别数据的数据,应包含“ m”。例如,在该示例中,我不希望有1mm,因为我的数据聚合级别较低(11,12)。同样,我也不想有11m,因为我的数据聚合级别较低(111,112)。我想拥有12m。因为应该存在121和122上的数据(cfr ls.prod.cat
),但是仅在更高的聚合级别上报告了该数据(12)。
我知道这是一个非常具体的问题,但是如果有人可以提供帮助,我将不胜感激。
----更新2 ---
考虑更复杂的数据集
df3 <- <- data.frame(
"Reporter" = c("USA", "USA", "USA", "USA", "USA", "USA","USA", "USA",
"USA","USA","EU", "EU","EU","EU","EU", "EU","EU","EU","EU", "EU",
"USA", "USA", "USA", "USA", "USA", "USA","USA", "USA", "USA","USA"),
"Partner" = c( "EU", "EU","EU","EU", "EU","EU","EU",
"EU","EU","EU","USA", "USA", "USA","USA","USA", "USA",
"USA","USA","USA", "USA", "EU", "EU","EU","EU", "EU","EU","EU",
"EU","EU","EU"),
"Product cat." = c("1", "11", "111", "112", "12","2", "21","211", "22",
"3", "1", "11", "111", "112", "2", "21", "211", "212", "22", "221",
"1", "11", "111", "112", "12","2", "21","211", "22", "3"),
"Year" = c(1970, 1970, 1970, 1970, 1970,1970, 1970, 1970, 1970, 1970,
1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1980, 1980,
1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980),
"Val" = c( 100, 50, 25, 5, 40, 200, 170, 170, 30, 220, 190, 190, 120,
30, 300, 200, 150, 50, 100, 100, 150, 50, 25,25, 100, 300, 120, 100,
160, 200),
stringsAsFactors = FALSE)
当我在代码上运行Function fillLevel时
fillLevel <- function(x, width = 3, fill = "m"){ sp <- split(x, substr(x, 1, 1)) sp <- lapply(seq_along(sp), function(i){ n <- nchar(sp[[i]]) if(all(n < 3)){ j <- which(n == max(n)) sp[[i]][j] <- gsub(" ", "m", formatC(sp[[i]][j], width = -3)) } sp[[i]] }) unname(unlist(sp))}
发生一些奇怪的事情
m.df3 <- df3 %>% mutate(m.prodcat = fillLevel(Product cat.))
特别是,m.prodcat
类别与product cat.
不对应。
例如,美国向欧盟出口产品类别的更改。 2到m.prodcat 1 ,来自产品cat。 21到m.prodcat 11等。还有许多其他不匹配的地方。
有人知道原因吗?非常感谢您的帮助
答案 0 :(得分:2)
在您发表评论后,这是我对问题的理解的基本R方法。
我创建了另一个具有两行额外数据集的数据集,目的是使代码上升到聚合的第二层。
df2 <- data.frame("Reporter" = c("USA", "USA", "USA", "USA", "USA","USA", "USA", "USA"),
"Partner" = c( "EU", "EU","EU","EU", "EU","EU","EU", "EU"),
"Product cat." = c("1", "11", "111", "122", "12", "2", "3", "31"),
"Year" = c(1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970),
"trade value" = c( 100, 50, 25, 5, 40, 220, 120, 20), stringsAsFactors = FALSE)
fillLevel <- function(x, width = 3, fill = "m"){
sp <- split(x, substr(x, 1, 1))
sp <- lapply(seq_along(sp), function(i){
n <- nchar(sp[[i]])
if(all(n < 3)){
j <- which(n == max(n))
sp[[i]][j] <- gsub(" ", "m", formatC(sp[[i]][j], width = -3))
}
sp[[i]]
})
unname(unlist(sp))
}
fillLevel(df$Product.cat.)
#[1] "1" "11" "111" "122" "12" "2mm"
fillLevel(df2$Product.cat.)
#[1] "1" "11" "111" "122" "12" "2mm" "3" "31m"
现在将函数的结果分配给您想要的任何值,无论是新列还是原始列。
答案 1 :(得分:2)
这里是str_pad
library(dplyr)
library(stringr)
df %>%
mutate(Product.cat. = str_pad(Product.cat., width = 3, pad = "m", side = "right"))
# Reporter Partner Product.cat. Year trade.value
#1 USA EU 1mm 1970 100
#2 USA EU 11m 1970 50
#3 USA EU 111 1970 25
#4 USA EU 122 1970 5
#5 USA EU 12m 1970 40
#6 USA EU 2mm 1970 220
答案 2 :(得分:0)
另一种方法是使用stri_pad_rigth()
中的stringi
:
library(stringi)
library(dplyr)
mutate(df, Product.cat. = stri_pad_right(Product.cat., 3, 'm'))
Reporter Partner Product.cat. Year trade.value
1 USA EU 1mm 1970 100
2 USA EU 11m 1970 50
3 USA EU 111 1970 25
4 USA EU 122 1970 5
5 USA EU 12m 1970 40
6 USA EU 2mm 1970 220
readr::str_pad()
在后台使用stringi::stri_pad_*()
函数:
> str_pad
function (string, width, side = c("left", "right", "both"), pad = " ")
{
side <- match.arg(side)
switch(side, left = stri_pad_left(string, width, pad = pad),
right = stri_pad_right(string, width, pad = pad), both = stri_pad_both(string,
width, pad = pad))
}
<bytecode: 0x566a028>
<environment: namespace:stringr>