(编辑以反映帮助......我在格式化方面表现不佳,但感谢反馈)
我有点卡在我怀疑是一个容易解决的问题上。我有多个不同的数据集,我已加载到R中,所有这些数据集都有不同的观察数,但所有数据集都有两个名为“A1”,“A2”和“A3”的变量。我想在三个数据帧的每一个中创建一个新变量,如果A3包含大于零的值,则包含“A1”中保存的值,如果A3包含小于零的值,则该值保存在“A2”中。看起来很简单,对吧?
我对此代码的尝试使用了这个虚假数据:
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具有在多个数据帧中创建相同命名变量的功能,但我尝试用lapply执行此操作:
mylist=list(df1,df2)
lapply(mylist,function(x){
x$newVar=x$A1
x$newVar[x$A3>0]=x$A2[x$A3>0]
return(x)
})
但是一旦离开lapply循环,newVar就无法使用了。例如,如果我要求新变量的平均值: 平均(DF1 $ newVar) [1] NA 警告信息: 在mean.default(df1 $ newVar)中: 参数不是数字或逻辑:返回NA
任何帮助将不胜感激 谢谢。
答案 0 :(得分: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
})
编辑(根据评论):
基本上总是发生在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]]