отдельные строки на основе условий во вложенных данных - PullRequest
0 голосов
/ 04 марта 2019

Я новичок в 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", "112", "12", "2"), 
"Product Description" = c("Food", "Fruit", "Apple", 
"Banana", "Meat", "Manifactured"),
"Year" = c(1970, 1970, 1970, 1970, 1970, 1970), 
"trade value" = c( 100, 50, 30, 20, 50, 220), 
stringsAsFactors = FALSE)

У меня есть наблюдения за торговлей за год.Вектор 'product.cat' указывает, какой товар экспортируется.Чем больше цифр имеет product.cat , тем больше дезагрегируется торговая информация.Например, product.cat. 111 (например, яблоко) и 112 (например, бананы) являются категориями субпродуктов категории продукта 11 (например, фрукты).То же самое относится и к более высоким уровням агрегации.Категория продукта 11 (фрукты) - это подкатегория product.cat 1 (продукты питания) вместе с product.cat 12 (мясо).Следует отметить, что данные в более низких категориях вкладываются в более высокий уровень агрегирования.Следовательно, значение product.cat 11 (50) равно значению product.cat 111 (30) + product.cat 112 (20),

Для проведения анализа мне нужно идентифицировать те значения, которые не представлены на самом дезагрегированном уровне, т. Е. Мне нужно идентифицировать данные, которые не представлены на трехзначном уровне.

Моя проблема в том, что для некоторых наблюдений за год в стране у меня есть точные данные, представленные на всех уровнях агрегации (например, 1,11,111,112), в то время как для других у меня есть данные только на более высоком уровне агрегирования (например, 12 и 2).Например, в моем примере у меня есть только product.cat 12 (мясо), но нет данных о том, какой вид мяса product.cat 121 (свинина), продукт.cat 122 (телятина).Аналогично, в этом примере данные о product.cat 2 (производство) не сообщаются на более низких уровнях.мы не знаем, является ли product.cat 21 (одежда) или product.cat 22 (изделия из дерева).

Другими словами, у меня есть данные, представленные на2-значный (12) или первый уровень (2), о котором можно сообщить на 3-значном уровне. Следует отметить, что каждая категория должна быть дезагрегирована по 3-значному уровню

  • Что я хотел бы сделать, так это найти способ индивидуализировать все данные исключительно , о которых сообщается на более высоком уровне агрегации, и изменяют свое имя product.cat, добавляя в конце "m".
  • После манипулирования product.cat 12 должно стать * 12m , чтобы указать, что данные были представлены только со 2-й цифры.Точно так же я хотел бы идентифицировать экспорт, о котором сообщается только в первой цифре.product.cat 2 должен стать 2 мм , чтобы отразить, что данные были представлены только по первой цифре.

Конечно, толькоДанные, для которых у меня есть информация исключительно на более высоком уровне агрегации - т.е. в примерах 12 и 2 - должны включать «m» s.Например, в этом примере я не хочу иметь 1 мм, поскольку у меня есть данные с более низким уровнем агрегирования (11,12).Точно так же я не хочу иметь 11 млн., Потому что у меня есть данные на более низких уровнях агрегации (111 112).Я хотел бы иметь 12 м и 2 мм, потому что данные представляются только на более высоком уровне агрегации (12 и 2).

Я знаю, что это очень специфический вопрос, но я был бы очень признателен, если бы кто-нибудьможет помочь.

Примечание : в реальном наборе данных из-за погрешностей измерения сумма дезагрегированных значений не всегда идеально дополняет более высокий уровень агрегирования.(например, 111 + 112 может быть> 11).Следовательно, в идеале, чтобы решить эту проблему, я ищу функцию, которая может указать, когда добавлять m на основе количества цифр, разделенных на страну, партнера, год, а не на сумму проданного значения.

Я действительно благодарю всех, кто мог бы помочь мне с этим, это было бы огромным шагом вперед для моего исследования.

---- попытки

Я былработает над этой функцией, но она, кажется, не делает то, что я ищу.Может быть, кто-то может выяснить, что идет не так

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))
}

df <- df%>% mutate(prdcat2 = fillLevel(df$Product.cat.))

Как вы можете видеть, он только индивидуализирует 2 мм, но не 12 м .Более того, когда я запускаю его на более сложных кодах, это портит порядок моих данных.Я думаю, что это относится к sp <- lapply(seq_along(sp), но я не уверен, как это сделать.

Лучший

1 Ответ

0 голосов
/ 04 марта 2019

Вот один из способов сделать это:

library(data.table)
setDT(df)

# tag levels
df[, lvl := nchar(Product.cat)]
df[lvl < 3L, has_subcat := FALSE]

# use level-3 observations to flag level-2s as okay    
df[
  df[lvl == 3, .(Reporter, Partner, Year, Product.cat = substr(Product.cat, 1, 2))],
  on=.(Reporter, Partner, Year, Product.cat),
  has_subcat := TRUE
]

# use level-2 observations to flag level-1s as okay    
df[
  df[lvl == 2, .(Reporter, Partner, Year, Product.cat = substr(Product.cat, 1, 1))],
  on=.(Reporter, Partner, Year, Product.cat),
  has_subcat := TRUE
]

# create new cat, flagging observations with no subcategories
df[, newcat := Product.cat]
df[has_subcat == FALSE, newcat := paste0(Product.cat, strrep("m", 3-lvl))]

   Reporter Partner Product.cat Product.Description Year trade.value lvl has_subcat newcat
1:      USA      EU           1                Food 1970         100   1       TRUE      1
2:      USA      EU          11               Fruit 1970          50   2       TRUE     11
3:      USA      EU         111               Apple 1970          30   3         NA    111
4:      USA      EU         112              Banana 1970          20   3         NA    112
5:      USA      EU          12                Meat 1970          50   2      FALSE    12m
6:      USA      EU           2        Manifactured 1970         220   1      FALSE    2mm

Я предполагаю, что это должно быть сделано отдельно для Репортер-Партнер-Год.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...