ใน R ฉันมีกรอบข้อมูลประกอบไปด้วยฉลากระดับC (ปัจจัย) และสองวัดM1และM2 ฉันจะคำนวณความสัมพันธ์ระหว่างM1และM2ในแต่ละชั้นเรียนได้อย่างไร
โดยหลักการแล้วฉันจะได้กรอบข้อมูลกลับมาหนึ่งแถวสำหรับแต่ละชั้นเรียนและสองคอลัมน์นั่นคือป้ายชื่อชั้นCและสหสัมพันธ์
ใน R ฉันมีกรอบข้อมูลประกอบไปด้วยฉลากระดับC (ปัจจัย) และสองวัดM1และM2 ฉันจะคำนวณความสัมพันธ์ระหว่างM1และM2ในแต่ละชั้นเรียนได้อย่างไร
โดยหลักการแล้วฉันจะได้กรอบข้อมูลกลับมาหนึ่งแถวสำหรับแต่ละชั้นเรียนและสองคอลัมน์นั่นคือป้ายชื่อชั้นCและสหสัมพันธ์
คำตอบ:
แพคเกจ plyr เป็นวิธีที่จะไป
นี่เป็นวิธีง่ายๆ:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
head(xx)
require(plyr)
func <- function(xx)
{
return(data.frame(COR = cor(xx$a, xx$b)))
}
ddply(xx, .(group), func)
ผลลัพธ์จะเป็น:
group COR
1 1 0.05152923
2 2 -0.15066838
3 3 -0.04717481
4 4 0.07899114
หากคุณมีแนวโน้มที่จะใช้ฟังก์ชั่นในแพ็คเกจพื้นฐานคุณสามารถใช้by
ฟังก์ชั่นแล้วรวบรวมข้อมูลอีกครั้ง:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
head(xx)
# This returns a "by" object
result <- by(xx[,2:3], xx$group, function(x) {cor(x$a, x$b)})
# You get pretty close to what you want if you coerce it into a data frame via a matrix
result.dataframe <- as.data.frame(as.matrix(result))
# Add the group column from the row names
result.dataframe$C <- rownames(result)
by
แต่ไม่สามารถหาวิธีแปลงผลลัพธ์ให้เป็นกรอบข้อมูลได้
อีกตัวอย่างหนึ่งที่ใช้แพ็คเกจพื้นฐานและข้อมูลตัวอย่างของ Tal:
DataCov <- do.call( rbind, lapply( split(xx, xx$group),
function(x) data.frame(group=x$group[1], mCov=cov(x$a, x$b)) ) )
plyr
ทำ แต่ให้การควบคุมที่ดีกว่าถึงแม้ว่ามันจะไม่สะอาด ความคิดเห็นของฉันจะเปลี่ยนหากวิธีการแก้ปัญหามีโปรไฟล์เวลา / หน่วยความจำดีกว่า ฉันไม่ได้เปรียบเทียบพวกเขา
ใช้ data.table สั้นกว่า dplyr
dt <- data.table(xx)
dtCor <- dt[, .(mCor = cor(M1,M2)), by=C]
นี่คือวิธีการที่คล้ายกันซึ่งจะให้ตารางกับค่า n และ p สำหรับแต่ละสหสัมพันธ์เช่นกัน (ปัดเศษเป็นทศนิยม 3 ตำแหน่งเพื่อความสะดวก):
library(Hmisc)
corrByGroup <- function(xx){
return(data.frame(cbind(correl = round(rcorr(xx$a, xx$b)$r[1,2], digits=3),
n = rcorr(xx$a, xx$b)$n[1,2],
pvalue = round(rcorr(xx$a, xx$b)$P[1,2], digits=3))))
}
นี่คือโซลูชันที่ทันสมัยกว่าโดยใช้ dplyr
แพ็คเกจ (ซึ่งยังไม่มีเมื่อถามคำถาม):
สร้างอินพุต:
xx <- data.frame(group = rep(1:4, 100), a = rnorm(400) , b = rnorm(400) )
คำนวณสหสัมพันธ์:
library(dplyr)
xx %>%
group_by(group) %>%
summarize(COR=cor(a,b))
ผลลัพธ์:
Source: local data frame [4 x 2]
group COR
(int) (dbl)
1 1 0.05112400
2 2 0.14203033
3 3 -0.02334135
4 4 0.10626273
plyr
แพ็คเกจดีใช่มั้ย :)