2013-08-19 4 views
2

(отредактирован, чтобы отразить помощь ... Я не делаю большой с форматированием, но оценить обратную связь)перекодирования более нескольких кадров данных в R

я немного застрял на том, что я подозреваю, что это достаточно легко проблема. У меня есть несколько разных наборов данных, которые я загрузил в R, все из которых имеют разные числа наблюдений, но все они имеют две переменные с именами «A1», «A2» и «A3». Я хочу создать новую переменную в каждом из трех фреймов данных, которые содержат значение, содержащееся в «A1», если A3 содержит значение больше нуля, а значение, удерживаемое в «A2», если A3 содержит значение, меньшее нуля. Кажется, достаточно просто, не так ли?

Моя попытка этого кода использует этот лже-данные:

set.seed(1) 
A1=seq(1,100,length=100) 
A2=seq(-100,-1,length=100) 
A3=runif(100,-1,1) 
df1=cbind(A1,A2,A3) 

A3=runif(100,-1,1) 
df2=cbind(A1,A2,A3) 

Я около тысячи процентов уверен, что R имеет некоторые функциональные возможности для создания такой же именем переменной в нескольких кадрах данных, но я пытался делая это с использованием:

mylist=list(df1,df2) 
lapply(mylist,function(x){ 
    x$newVar=x$A1 
    x$newVar[x$A3>0]=x$A2[x$A3>0] 
    return(x) 
}) 

Но новый вал недоступен для меня, как только я покину петлю. Например, если я спрошу для среднего новых переменный: среднего (df1 $ newVar) [1] NA Предупреждения Сообщения: В mean.default (df1 $ newVar): аргумент не является числовым или логическим: возвращение NA

Любая помощь будет оценена по достоинству.
Спасибо.

ответ

3

Ну, в первую очередь, df1 и df2 не являются data.frames, но матрицы (синтаксис доллара не работает на матрицах).
В самом деле, если вы делаете:

set.seed(1) 
A1=seq(1,100,length=100) 
A2=seq(-100,-1,length=100) 
A3=runif(100,-1,1) 
df1=as.data.frame(cbind(A1,A2,A3)) 

A3=runif(100,-1,1) 
df2=as.data.frame(cbind(A1,A2,A3)) 

mylist=list(df1,df2) 
lapply(mylist,function(x){ 
    x$newVar=x$A1 
    x$newVar[x$A3>0]=x$A2 
}) 

код почти работает, но дает некоторые предупреждения. Фактически, в последней строке функции, вызванной lapply, все еще есть ошибка. Если вы измените это так, он работает, как ожидалось:

lapply(mylist,function(x){ 
    x$newVar=x$A1 
    x$newVar[x$A3>0]=x$A2[x$A3>0] # you need to subset x$A2 otherwise it's too long 
    return(x) # better to state explicitly what's the return value 
}) 

EDIT (в соответствии с комментарием):

в основном всегда происходит в R, функции не мутировать существующие объекты, но возвращение новые объекты.
Таким образом, в этом случае df1 и df2 остались прежними, но lapply возвращает список с ожидаемыми 2 новых data.frames т.е.:

resultList <- lapply(mylist,function(x){ 
    x$newVar=x$A1 
    x$newVar[x$A3>0]=x$A2[x$A3>0] 
    return(x) 
}) 

newDf1 <- resultList[[1]] 
newDf2 <- resultList[[2]] 
+0

Спасибо за возвращение ко мне так быстро, и помогает мне уйти от ошибок. Теперь у меня есть: ' lapply (mylist, function (x) { x $ newVar = x $ A1 x $ newVar [x $ A3> 0] = x $ A2 [x $ A3> 0] return (x) }) ' Но когда я позже посмотрю на df1 и df2, они все еще имеют только 3 переменные: A1, A2 и A3. Нет «newVar». наименования (df1) [1] "A1" "A2" "A3" Что я делаю неправильно? – Molly

+0

@Molly: проверьте мои изменения;) – digEmAll

+0

Отлично! Спасибо. – Molly

Смежные вопросы