2015-09-18 3 views
1

У меня есть список фреймов данных, имеющих ту же структуру. Мне нужно перекодировать переменную в каждом кадре данных на основе значения другой переменной. Я нашел здесь решения, которые подтолкнули меня, но через много часов я все еще отстаю.R: Вложенные инструкции if else в список фреймов данных

Мои кадры данных выглядит следующим образом:

код
$Test14 
    Class Total 
1 201  1 
2 203 14 
3 204  3 
4 205  7 
5 206  7 
6 207  1 
7 211  2 
8 212  1 
9 213 16 
10 288 27 
11 299  9 
12 517  1 
13 592  2 
14 593  8 

Каждый класс попадает в более широкую категорию MajorClass. Я пытаюсь присоединить еще один те MajorClass, чтобы я мог использовать данные на простом английском языке. Так что-то вроде этого:

$Test14 
    Class Total MajorClass 
1 201   1 Reg Residential 
2 203  14 Reg Residential 
3 204   3 Reg Residential 
4 205   7 Reg Residential 
5 206   7 Reg Residential 
6 207   1 Reg Residential 
7 211   2 Reg Residential 
8 212   1 Reg Residential 
9 213  16 NonReg Residential 
10 288  27 NonReg Residential 
11 299   9 NonReg Residential 
12 517   1 Commercial 
13 592   2 Commercial 
14 593   8 Industrial 

Моя мысль была, чтобы попытаться использовать lapply вместо для цикла, чтобы получить MajorClass для каждой строки, а затем использовать cbind, чтобы вытащить все это вместе позже. Закрытие я пришел, используя следующий код:

> MajorClass <- lapply(mydata, function(i) { 
>  i$MajorClass <- "" 
>  if (i$Class == '200' || i$Class == '202' || i$Class == '203' || i$Class  == '204' || i$Class == '205' || i$Class == '206' || i$Class == 
> '207' || i$Class == '208' || i$Class == '209' || i$Class == '210' || 
> i$Class == '211' || i$Class == '212' || i$Class == '216' || i$Class == 
> '234' || i$Class == '278' || i$Class == '295') 
>   i$MajorClass <- "Reg Residential" 
>  else 
>   if (i$Class == '239' || i$Class == '240' || i$Class == '241' || i$Class == '201' || i$Class == '213' || i$Class == '224' || i$Class 
> == '225' || i$Class == '236' || i$Class == '288' || i$Class == '290' || i$Class == '297' || i$Class == '299') 
>    i$MajorClass <- "NonReg Residential" ... and so on ... 

Но он возвращает только одно значение для последней записи в каждом кадре данных. Я пробовал несколько вариантов этого, и попытался использовать цикл for, все безрезультатно. Кроме того, мое (ограниченное) понимание заключается в том, что более эффективно использовать функции apply вместо циклов.

Любая помощь или указатель в правильном направлении были бы очень признательны. Как я уже сказал, я много искал на этом сайте и других и подошел близко, но не достаточно близко. Еще раз спасибо!

ответ

1

Что вы пытаетесь сделать, это сопоставить значения из одной таблицы в другую, что можно сделать легко с помощью join. Это соответствует элементам двух таблиц общим (и одинаково названным) столбцом.

Для этого вам нужна справочная таблица, в которой каждый другой class имеет свой связанный MajorClass. (Я генерироваться некоторые фиктивные данные)

#install.packages("dplyr") 
library(dplyr) 

test <- list(test14 = data.frame(class = c("201", "203","205"), total=c(1,3,7), 
          stringsAsFactors = F)) 
reference_table <- data.frame(class = c("201","202","203","204","205"), 
          MajorClass=c("Reg","Reg","NonReg","comercial","comercial"), 
          stringsAsFactors = F) 

Теперь вы можете сопоставить его с каждым кадром данных, с помощью lapply

output.list <- lapply(test, function(x) left_join(x, reference_table, by="class")) 
$test14 
    class total MajorClass 
1 201  1  Reg 
2 203  3  NonReg 
3 205  7 comercial 

или свернуть все кадры данных из вашего списка в один (вы можете сделайте это, если они имеют одинаковую структуру), а затем сразу сопоставьте всю таблицу.

data <- bind_rows(test) 
output <- left_join(data, reference_table, by="class") 

    class total MajorClass 
    (chr) (dbl)  (chr) 
1 201  1  Reg 
2 203  3  NonReg 
3 205  7 comercial 
+1

Или без использования 'dplyr' (но при условии, справочную таблицу), вы можете просто сделать' тест $ MajorClass <- коэффициент (тест $ класс, уровень = reference_table $ класс, наклейки = reference_table $ MajorClass) ' , Всегда хорошо иметь альтернативу в базе R. –

+0

Конечно! Вот как я бы это описал, если бы я использовал SQL. Я уже думал об этом. Очень ценю это Винсент. –

+0

@ antoine-sac, я редко использую «факторы» и никогда не думал использовать их таким образом! Благодаря! –

0

Я предполагаю, что у вас есть справочная таблица, как описывает Vicent Boned. Вы можете использовать базу R для выполнения задания.

test$MajorClass <- factor(test$class, levels=reference_table$class, labels=reference_table$MajorClass)