2014-10-01 1 views
0

Привет У меня есть набор данных, который выглядит, как этотСоздание новой переменной

bankname bankid year totass invloc1 invamt1 invloc2 invamt2 invloc3 invamt3 
Bank A 1 1881 244789 Philadelphia 7250.32 New York 20218.20 Philadelphia 29513.4 
Bank B 2 1881 195755 Pittsburgh 10243.60 NA 1851.51 NA NA 
Bank C 3 1881 107736 New York 13357.80 Wilkes-Barre 17761.20 NA NA 
Bank D 4 1881 170600 Philadelphia 3.35 Philadelphia 2.00 NA NA 
Bank E 5 1881 32000000 New York 351266.00 New York 314012.00  NA 

, но я хочу, чтобы создать новую переменную с именем NY_tot использованием invloc и invamt переменных для каждого банка. Для каждого банка, если их invloc является Нью-Йорком, затем суммируйте invamt. invloc1 и invamt1 идут вместе. Следовательно, я хочу, чтобы этот набор данных выглядел так.

bankname bankid year totass invloc1 invamt1 invloc2 invamt2 invloc3 invamt3 NY_tot 
Bank A 1 1881 244789 Philadelphia 7250.32 New York 20218.20 Philadelphia 29513.4 20218.20 
Bank B 2 1881 195755 Pittsburgh 10243.60 NA 1851.51 NA NA 0 
Bank C 3 1881 107736 New York 13357.80 Wilkes-Barre 17761.20 NA NA 13357.80 
Bank D 4 1881 170600 Philadelphia 3.35 Philadelphia 2.00 NA NA 0 
Bank E 5 1881 32000000 New York 351266.00 New York 314012.00  NA 665278 

Вот набор данных Я использую

bankname <- c("Bank A","Bank B","Bank C","Bank D","Bank E") 
bankid <- c(1, 2, 3, 4, 5) 
year<- c(1881, 1881, 1881, 1881, 1881) 
totass <- c(244789, 195755, 107736, 170600, 32000000) 
invloc1 <-c("Philadelphia","Pittsburgh","New York","Philadelphia","New York") 
invamt1<-c(7250.32,10243.6,13357.8,3.35,351266) 
invloc2<-c("New York","NA","Wilkes-Barre","Philadelphia","New York") 
invamt2<-c(20218.2,1851.51,17761.2,2,314012) 
invloc3<-c("Philadelphia","NA","NA","NA","") 
invamt3<-c(29513.4,NA,NA,NA,NA) 
bankdata<-data.frame(bankname, bankid,year,totass, invloc1, invamt1, invloc2, invamt2, invloc3, invamt3) 

Когда я попытался следующий код:

Изменение коэффициента переменных (invloc) к характеру

i <- sapply(bankdata, is.factor) 
bankdata[i] <- lapply(bankdata[i], as.character) 

Затем создать новая переменная

for(i in 1:nrow(bankdata)){ 
bankdata$NY_tot<-0 
for(j in 1:3){ 
if((!is.na(bankdata[i,paste("invloc",j,sep="")])) && (bankdata[i,paste("invloc",j,sep="")]=="New York")){ 
    if (!is.na(bankdata[i,paste("invamt",j,sep="")])){ 
    bankdata$NY_tot[i]<-bankdata$NY_tot[i]+bankdata[i,paste("invamt",j,sep="")] 
     } 
    } 
    } 
} 

Я получаю 0s в своей переменной NY_tot. Можешь мне сказать почему?

Спасибо заранее!

+1

Поскольку вы переопределяете 'bankdata $ NY_tot <-0' для каждой строки. Вероятно, вы захотите сделать это за пределами цикла. – shadow

+2

Вы используете циклы 'for', где вы должны использовать vectorisation. Это приводит к медленному коду. – Roland

+0

Как я могу сделать это более эффективно? Можете ли вы дать мне образцы кодов? Всем спасибо. –

ответ

1

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

В этом случае ваше решение - ifelse. Я несколько путают, какие столбцы вы хотите работать, но попробовать что-то вроде этого:

bankdata$NY_tot=ifelse(bankdata$invloc1=="New York",sum(bankdata$invamt1,bankdata$invamt2),NA) 

Что здесь происходит? ifelse работает так:

ifelse(conition, value_if_true, value_if_false) 

Таким образом, в вашем случае функция проверяет, является ли значение invloc1 является "New York", возвращает сумму, если она есть, и NA, если это не так. Самое приятное в том, что он автоматически выполняет эту строку за строкой, поэтому вам не нужно вручную выполнять итерацию по файловому кадру, что вызывает проблемы в вашем коде выше.

Edit: как это было предложено @Richard Скривен ниже, вы можете не вводить на имя dataframe четыре раза с помощью with или within, например:

bankdata<-within(bankdata, NY_tot=ifelse(invloc1=="New York"),sum(invamt1,invamt2),NA) 

Это отличный трюк, который я буду использовать для остальная часть моей жизни, которая в основном говорит R, что все указанные имена переменных связаны с bankdata, поэтому вам не нужно ее печатать.

+1

Может быть хорошо, чтобы включить 'with' в ваш ответ –

+0

@Richard Scriven, я уже более года программирую R, и не обнаружил« с/внутри »... Я думаю, вы изменили мою жизнь. – Joe

+0

И вы тоже в другой среде. 'a <-" H "; x <- list (a = 1, b = 2); с (x, list (ls(), mget (ls()), get ("a", .GlobalEnv))). Довольно аккуратный материал –