2

(编辑以反映帮助......我在格式化方面做得不好,但感谢反馈)

我有点坚持我怀疑是一个足够简单的问题。我有多个不同的数据集已加载到 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 了。例如,如果我询问新变量的平均值: mean(df1$newVar) [1] NA 警告消息:在 mean.default(df1$newVar) 中:参数不是数字或逻辑:返回 NA

任何帮助,将不胜感激。
谢谢你。

4

1 回答 1

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 个新数据帧的列表,即:

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]]
于 2013-08-19T21:26:03.930 回答