为什么 sapply 返回一个我需要转置的矩阵,然后转置后的矩阵不会附加到数据帧?
我希望能深入了解为什么会发生这种情况,以及如何更雄辩地做到这一点。
当我使用 sapply 时,我希望它返回一个 3x2 矩阵,但它返回一个 2x3 矩阵。这是为什么呢?为什么很难将其附加到另一个数据框?
a <- data.frame(id=c('a','b','c'), var1 = c(1,2,3), var2 = c(3,2,1))
out <- sapply(a$id, function(x) out = a[x, c('var1', 'var2')])
#out is 3x2, but I would like it to be 2x3
#I then want to append t(out) (out as a 2x3 matrix) to b, a 1x3 dataframe
b <- data.frame(var3=c(0,0,0))
当我尝试附加这些时,
b[,c('col2','col3')] <- t(out)
我得到的错误是:
Warning message:
In `[<-.data.frame`(`*tmp*`, , c("col2", "col3"), value = list(1, :
provided 6 variables to replace 2 variables
尽管以下内容似乎给出了所需的结果:
rownames(out) <- c('col1', 'col2')
b <- cbind(b, t(out))
我无法对变量进行操作:
b$var1/b$var2
返回
Error in b$var1/b$var2 : non-numeric argument to binary operator
谢谢!
I would appreciate insight into why this happens and how I might do this more eloquently.
When I use sapply, I would like it to return a 3x2 matrix, but it returns a 2x3 matrix. Why is this? And why is it difficult to attach this to another data frame?
a <- data.frame(id=c('a','b','c'), var1 = c(1,2,3), var2 = c(3,2,1))
out <- sapply(a$id, function(x) out = a[x, c('var1', 'var2')])
#out is 3x2, but I would like it to be 2x3
#I then want to append t(out) (out as a 2x3 matrix) to b, a 1x3 dataframe
b <- data.frame(var3=c(0,0,0))
when I try to attach these,
b[,c('col2','col3')] <- t(out)
The error that I get is:
Warning message:
In `[<-.data.frame`(`*tmp*`, , c("col2", "col3"), value = list(1, :
provided 6 variables to replace 2 variables
although the following appears to give the desired result:
rownames(out) <- c('col1', 'col2')
b <- cbind(b, t(out))
I can not operate on the variables:
b$var1/b$var2
returns
Error in b$var1/b$var2 : non-numeric argument to binary operator
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
扩展 DWin 的答案:查看
out
对象的结构会有所帮助。它解释了为什么b$var1/b$var2
不符合您的预期。apply
系列函数设计用于处理向量和数组,因此在将它们与 data.frames(通常是向量列表)一起使用时需要小心。您可以通过lapply
利用 data.frames 是列表这一事实来发挥您的优势。To expand on DWin's answer: it would help to look at the structure of your
out
object. It explains whyb$var1/b$var2
doesn't do what you expect.The
apply
family of functions are designed to work on vectors and arrays, so you need to take care when using them with data.frames (which are usually lists of vectors). You can use the fact that data.frames are lists to your advantage withlapply
.首先是一些 R 符号。如果您查看
sapply
的代码,您就会找到问题的答案。sapply
函数检查列表长度是否都相等,如果是,它首先“unlist()”它们,然后将该系列列表作为array 的数据参数()
。由于array
(如 matrix() )默认情况下按列主要顺序排列其值,这就是您所得到的。名单被翻转了。如果您不喜欢它,那么您可以定义一个新函数tsapply
,它将返回转置值:...一个 3 x 2 矩阵。
First a bit of R notation. The If you look at the code for
sapply
, you will find the answer to your question. Thesapply
function checks to see if the list lengths are all equal, and if so, it first "unlist()"s them and then takes that series of lists as the data argument toarray()
. Sincearray
(like matrix() ) by default arranges its values in column major order, that is what you get. The lists get turned on their side. If you don't like it then you can define a new functiontsapply
that will return the transposed values:... a 3 x 2 matrix.
查看 plyr 包中的 ddply
Have a look at ddply from the plyr package