【问题标题】:Lapply to the list of data frames in R应用于 R 中的数据框列表
【发布时间】:2015-01-14 21:00:24
【问题描述】:
> df1 <- data.frame(A = 1:10, B= 11:20)
> df2 <- data.frame(A = 21:30, B = 31:40)
> ddata <- list(df1,df2)

我的目标是对列表的每个数据框执行 A 列和 B 列的关联。 即

cor (ddata[[1]]$A,ddata[[1]]$B)
cor (ddata[[2]]$A,ddata[[2]]$B)

为此,我正在使用lapply,但我做错了什么,请帮忙。

lapply(ddata, cor)

【问题讨论】:

  • 试试lapply(ddata,function(x){ cor(x[[1]],x[[2]]) })
  • 嗨,谢谢您的解决方案有效,但我有疑问。当我在函数中引用 x[[1]] 时,它指的是整个数据框。那么它是如何在数据框的各个列之间执行 cor 的??
  • 我在下面添加了一个答案来详细说明我的评论。

标签: r list dataframe lapply


【解决方案1】:

您的代码的问题是,当您对整个 data.frame(所有数字列)调用 cor 时,它将返回一个相关性矩阵,其中包含所有列的成对相关性- 对角线上的值是各列与其自身的相关性(始终等于 1.00)。这在您的示例数据中不会立即显现出来,因为 cor(A,B) == cor(B,A) == cor(A,A) == cor(B,B) == 1 代表您的两个 data.frames。这在以下示例中更清楚:

df5 <- data.frame(A=rnorm(10),B=rnorm(10),C=rnorm(10))
R> cor(df5)
           A           B          C
A 1.00000000  0.05131293  0.6173047
B 0.05131293  1.00000000 -0.1312331
C 0.61730466 -0.13123314  1.0000000

无论如何,我认为您正在寻找单个相关而不是相关矩阵,这可以通过几种不同的方式实现 - 访问data.frame的列使用x[,1]x[,2] 或使用x[[1]]x[[2]]

此外,还有另一个语法选项;一种导致相关性的标量值,除了与上述两种情况不同,它保留matrix 类。这是使用x[1]x[2] 访问列,因为单括号(没有逗号)将产生一列data.frame

出于您的目的,上面直接提到的 3 种方法中的任何一种都应该是可以接受的 - 只要您传递 cor 两个对象,无论它们是(原子)数字向量(case [, ] 和 case [[ ]])还是单个data.frames(案例[ ]) - 该函数将评估为cor(x, y, ...)并返回单个相关。前两种方法和第三种方法之间的(细微)区别在于返回值的类别——numeric(原子)用于前者,matrix 用于后者——但这很可能是大图。


让我用几个例子来总结一下,使用这个数据:

set.seed(123)
df3 <- data.frame(
  A=rnorm(10),
  B=rnorm(10))
##
set.seed(321)
df4 <- data.frame(
  A=rnorm(10),
  B=rnorm(10))
##
dflist <- list(df3,df4)

A.结果类型是相关矩阵;结果类为matrix:

R> class(cor(df3)); cor(df3)
[1] "matrix"
          A         B
A 1.0000000 0.5776151
B 0.5776151 1.0000000

B.结果类型为单个相关值;结果类为matrix

R> class(cor(df3[1],df3[2])); cor(df3[1],df3[2])
[1] "matrix"
          B
A 0.5776151

C.结果类型为单个相关值;结果类为numeric

R> class(cor(df3[,1],df3[,2])); cor(df3[,1],df3[,2])
[1] "numeric"
[1] 0.5776151

D.结果类型为单个相关值;结果类为numeric

R> class(cor(df3[[1]],df3[[2]])); cor(df3[[1]],df3[[2]])
[1] "numeric"
[1] 0.5776151

同样,以下四个函数fA - fD对应上述情况A - D

fA <- function(y) {
  res <- lapply(y,cor)
  message(paste0("Element class: ",class(res[[1]])))
  res
}
##
fB <- function(y) {
  res <- lapply(y, function(x) {
    cor(x[1],x[2])
  })
  message(paste0("Element class: ",class(res[[1]])))
  res
}
##
fC <- function(y) {
  res <- lapply(y, function(x) {
    cor(x[,1],x[,2])
  })
  message(paste0("Element class: ",class(res[[1]])))
  res
}
##
fD <- function(y) {
  res <- lapply(y, function(x) {
    cor(x[[1]],x[[2]])
  })
  message(paste0("Element class: ",class(res[[1]])))
  res
}

在对象dflist 上运行它们给了我们

R> fA(dflist)
Element class: matrix
[[1]]
          A         B
A 1.0000000 0.5776151
B 0.5776151 1.0000000

[[2]]
           A          B
A  1.0000000 -0.1816951
B -0.1816951  1.0000000

##
R> fB(dflist)
Element class: matrix
[[1]]
          B
A 0.5776151

[[2]]
           B
A -0.1816951

##
R> fC(dflist)
Element class: numeric
[[1]]
[1] 0.5776151

[[2]]
[1] -0.1816951

##
R> fD(dflist)
Element class: numeric
[[1]]
[1] 0.5776151

[[2]]
[1] -0.1816951

【讨论】:

  • 另外我上面也没有解决,但是使用列访问操作符$,比如df3$A,相当于使用df3[,1]df3[[1]](或df3[,"A"]df3[["A"]])。
猜你喜欢
  • 1970-01-01
  • 2015-04-19
  • 1970-01-01
  • 2019-01-20
  • 2021-08-28
  • 2021-07-11
  • 2020-11-21
  • 2020-04-03
  • 2020-04-24
相关资源
最近更新 更多