2015-01-14 4 views
2
> df1 <- data.frame(A = 1:10, B= 11:20) 
> df2 <- data.frame(A = 21:30, B = 31:40) 
> ddata <- list(df1,df2) 

Наша цель - выполнить корреляцию столбца A и B в кадре данных списка. т.е.Lapply к списку фреймов данных в R

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

для этого я использую lapply но я делаю что-то неправильное, пожалуйста, помогите.

lapply(ddata, cor) 
+1

Попробуйте 'lapply (ddata, function (x) { cor (x [[1]], x [[2]]) })' – nrussell

+0

Привет, Спасибо, что ваше решение сработало, но у меня есть сомнения. Когда я ссылаюсь на x [[1]] в функции, он ссылается на весь фрейм данных справа .. Тогда как он выполняет cor между отдельными столбцами кадра данных? –

+0

Я добавил ответ ниже, чтобы подробно рассказать о моем комментарии. – nrussell

ответ

3

Проблема с кодом является то, что при вызове cor на все data.frame (все числовые столбцы), он будет возвращать корреляции матрицу, содержащий попарные корреляции всех столбцов - со значениями по диагонали являются корреляцией соответствующего столбца с самим собой (что всегда равно 1.00). Это не будет сразу видно с вашими примерными данными, поскольку cor(A,B) == cor(B,A) == cor(A,A) == cor(B,B) == 1 для ваших двух data.frame. Это ясно показано в следующем примере:

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 два объекты, являются ли они (атомные) числовые векторы (случай [, ] и случай [[ ]]) или одного столбцов data.frame s (случай [ ]) - функция будет оцениваться как 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 

В. Тип результата является одно значение корреляции; класс результатов: 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 

Д. Тип результата является одно значение корреляции; Результат класс 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 
+0

Также я не рассматривал это выше, но использование оператора доступа '' ', такого как' df3 $ A', эквивалентно использованию 'df3 [, 1]' или 'df3 [[1]]' (или 'df3 [," A "]' или 'df3 [[" A "]]'). – nrussell

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