R හි කණ්ඩායම් අනුව දත්ත සාරාංශ කරන්නේ කෙසේද? [වසා ඇත]


185

මට මේ ආකාරයට R දත්ත රාමුවක් ඇත:

        age group
1   23.0883     1
2   25.8344     1
3   29.4648     1
4   32.7858     2
5   33.6372     1
6   34.9350     1
7   35.2115     2
8   35.2115     2
9   35.2115     2
10  36.7803     1
...

මට පහත දැක්වෙන ආකාරයෙන් දත්ත රාමුවක් ලබා ගැනීමට අවශ්‍යයි:

group mean     sd
1     34.5     5.6
2     32.3     4.2
...

කණ්ඩායම් අංකය වෙනස් විය හැකි නමුත් ඇමතුම් මගින් ඔවුන්ගේ නම් සහ ප්‍රමාණය ලබා ගත හැකිය levels(factor(data$group))

ප්‍රති result ලය ලබා ගැනීම සඳහා දත්ත සමඟ කළ යුතු උපාමාරු මොනවාද?


ප්‍රති data ල දත්ත රාමුවේ කොමාව යන්නෙන් අදහස් කරන්නේ විශේෂ දෙයක්ද, නැතහොත් එය දශම ලක්ෂ්‍යයද?
mpiktas

සටහන් කිරීම ගැන ස්තූතියි. නිවැරදි කරන ලදි. මේවා ස්ථානීය ගැටළු (මම රුසියානු) - අපි දශම වෙන් කිරීම සඳහා කොමාව භාවිතා කරමු.
යූරි පෙට්‍රොව්ස්කි

3
මම එය සැක කළා. මෙම සියලු යුරෝපය බ්රිතාන්ය හැර කොමා භාවිතා කරයි.
mpiktas

4
බ්‍රිතාන්‍ය නොවූවත්, දශම බෙදුම්කරු සඳහා තිතට මම කැමැත්තෙමි.
රෝමන් ලුස්ට්‍රික්

1
මෙම වර්ගයේ ඕනෑම පසුකාලීන කේතීකරණ ප්‍රශ්න සඳහා බලන්න aggregate, tapplyපසුව stackoverflow.com බලන්න .
conjugateprior

Answers:


143

මෙන්න මේ plyr භාවිතා එක පේලියක් ප්රභේද්යයක් ddply :

dt <- data.frame(age=rchisq(20,10),group=sample(1:2,20,rep=T))
ddply(dt,~group,summarise,mean=mean(age),sd=sd(age))

මෙන්න නව පැකේජ දත්ත භාවිතා කරමින් තවත් එක් පේළි ප්‍රභේදයකි .

dtf <- data.frame(age=rchisq(100000,10),group=factor(sample(1:10,100000,rep=T)))
dt <- data.table(dtf)
dt[,list(mean=mean(age),sd=sd(age)),by=group]

පේළි 100k සහිත මේසයේ පමණක් මෙය කැපී පෙනේ. 2.53 Ghz Core 2 Duo ප්‍රොසෙසරයක් සහ R 2.11.1 සමඟ මගේ මැක්බුක් ප්‍රෝ හි වේලාවන්:

> system.time(aa <- ddply(dtf,~group,summarise,mean=mean(age),sd=sd(age)))
utilisateur     système      écoulé 
      0.513       0.180       0.692 
> system.time(aa <- dt[,list(mean=mean(age),sd=sd(age)),by=group])
utilisateur     système      écoulé 
      0.087       0.018       0.103 

අප භාවිතා කරන්නේ නම් තවදුරටත් ඉතිරිකිරීම් කළ හැකිය setkey:

> setkey(dt,group)
> system.time(dt[,list(mean=mean(age),sd=sd(age)),by=group])
utilisateur     système      écoulé 
      0.040       0.007       0.048 

2
lchl, මෙම නව දත්ත ටේබල් පැකේජය අත්හදා බැලීමට එය මට අවස්ථාවක් ලබා දුන්නේය . එය සැබවින්ම යහපත් බව පෙනේ.
mpiktas

7
Data.table සඳහා +6000. 100k ට වඩා කුඩා දත්ත කට්ටලවල පවා මට එය ddply ට වඩා වේගවත්ය (මට පේළි 20k එකක් ඇත). මා අයදුම් කරන කාර්යයන් සමඟ සම්බන්ධ විය යුතු දෙයක් විය යුතුය, නමුත් ddply සඳහා මිනිත්තු කිහිපයක් ගතවනු ඇත.
පරමාණුක

සරල යතුරු ලියනය: මම හිතන්නේ ඔබ අදහස් කළේ දෙවන කේත කොටස dt <- data.table(dtf)වෙනුවට dt <- data.table(dt). ඒ ආකාරයෙන්, ඔබ පැකේජයේ dtශ්‍රිතය වෙනුවට දත්ත රාමුවකින් දත්ත වගුව නිර්මාණය කරයි stats. මම එය සංස්කරණය කිරීමට උත්සාහ කළෙමි, නමුත් මට අක්ෂර හයක් යටතේ සංස්කරණ කළ නොහැක.
ක්‍රිස්ටෝපර් බොටම්ස්

මගේ (මෙම අවස්ථාවේ දී නිහතමානී නොවේ) මතය data.tableදත්ත සමුච්චය කිරීමට හොඳම ක්‍රමය වන අතර මෙම පිළිතුර විශිෂ්ටයි, නමුත් තවමත් මතුපිට සීරීමට පමණි. සින්ටැක්ටිකල් ලෙස උසස් වීම හැරුණු විට, එය අතිශයින්ම නම්‍යශීලී වන අතර සම්බන්ධ වීම සහ අභ්‍යන්තර යාන්ත්‍රික විද්‍යාව සම්බන්ධ බොහෝ දියුණු අංග ඇත. වැඩි විස්තර සඳහා නිතර අසන පැන, ගිතබ් පිටුව හෝ පා course මාලාව බලන්න.
ජෙනෝරාමා

100

එක් හැකියාවක් වන්නේ සමස්ත ශ්‍රිතය භාවිතා කිරීමයි . උදාහරණයක් වශයෙන්,

aggregate(data$age, by=list(data$group), FUN=mean)[2]

අපේක්ෂිත ප්‍රති .ලයේ දෙවන තීරුව ඔබට ලබා දෙයි.


1
ඔබගේ දේශීය උපකාරක සේවාදායකයට සම්බන්ධ නොවන්න :-) +1 නමුත් @ ස්ටෙෆන්ගේ ප්‍රතිචාරයට මගේ අදහස් බලන්න.
chl

ඇමතුමෙන් එය සිදු කළ data.frame(group=levels(factor(data$group)),mean=(aggregate(data$age, by=list(data$group), FUN=mean)$x),sd=(aggregate(data$age, by=list(data$group), FUN=sd)$x))නමුත් එය නිවැරදි ක්‍රමය යැයි මම නොසිතමි. බන්ධිත තීරු වල ප්‍රති results ල විවිධ අනුපිළිවෙලින් සිදුවනු ඇතැයි මට විශ්වාස නැත (එය කළ හැකි යැයි මම සිතමි). ඔබේ විරුද්ධත්වය කුමක්ද?
යූරි පෙට්‍රොව්ස්කි

9
Ur යූරි පේළි පිළිවෙලට නොවිය යුතුය, නමුත් එය කළ හැකි ක්‍රමයක් මෙන්න aggregate():aggregate(age ~ group, data=dat, FUN = function(x) c(M=mean(x), SD=sd(x)))
lockoff

ocklockedoff: මගේ පිළිතුර සම්පූර්ණ කිරීම ගැන ස්තූතියි!
ocram

27

ඔබ දත්ත රාමුවක් හසුරුවන බැවින්, dplyrපැකේජය එය කිරීමට වේගවත්ම ක්‍රමය විය හැකිය.

library(dplyr)
dt <- data.frame(age=rchisq(20,10), group=sample(1:2,20, rep=T))
grp <- group_by(dt, group)
summarise(grp, mean=mean(age), sd=sd(age))

හෝ ඒ හා සමානව, dplyr/ magrittrපයිප්ප ක්‍රියාකරු භාවිතා කිරීම :

library(dplyr)
dt <- data.frame(age=rchisq(20,10), group=sample(1:2,20, rep=T))
group_by(dt, group) %>%
 summarise(mean=mean(age), sd=sd(age))

පයිප්ප ක්‍රියාකරුගේ පූර්ණ භාවිතය සංස්කරණය කරන්න:

library(dplyr)
data.frame(age=rchisq(20,10), group=sample(1:2,20, rep=T)) %>%
  group_by(group) %>%
  summarise(mean=mean(age), sd=sd(age))

3
සඳහා +1 dplyr. එය බොහෝ R කාර්යයන් සරල කර ඇති අතර මෙම ක්‍රම බොහොමයක් යල්පැන ඇත.
gregmacfarlane

අවාසනාවකට නල ක්‍රියාකරු අනුවාදය සම්පූර්ණයෙන් භාවිතා කිරීම මට
ප්‍රයෝජනවත් නොවේ

ඔබ dplyr හෝ magrittr පටවා තිබේද?
බැස්ටියන් ක්වාස්ට්

ඔබට ස්තූතියි @bquast විසඳුම දෙසට යොමු කිරීම ගැන, සාරාංශගත කිරීමේ ශ්‍රිතය කැඳවනු ලැබුවේ ගැටලුව plyrවෙනුවට ය dplyr.
dagcilibili

12

නියමයි, dplyr විසඳුම එකතු කිරීම ගැන ස්තූතියි bquast!

එවිට dplyr සහ data.table ඉතා සමීප බව හැරෙනවා:

library(plyr)
library(dplyr)
library(data.table)
library(rbenchmark)

dtf <- data.frame(age=rchisq(100000,10),group=factor(sample(1:10,100000,rep=T)))
dt <- data.table(dtf)

setkey(dt,group)

a<-benchmark(ddply(dtf,~group,plyr:::summarise,mean=mean(age),sd=sd(age)),
         dt[,list(mean=mean(age),sd=sd(age)),by=group],
         group_by(dt, group) %>% summarise(mean=mean(age),sd=sd(age) ),
         group_by(dtf, group) %>% summarise(mean=mean(age),sd=sd(age) )
)

a[, c(1,3,4)]

data.table තවමත් වේගවත්ම වේ, dplyr () විසින් ඉතා සමීපව අනුගමනය කරන අතර එය data.table ට වඩා data.frame හි වේගයෙන් පෙනේ.

                                                              test elapsed relative
1 ddply(dtf, ~group, plyr:::summarise, mean = mean(age), sd = sd(age))   1.689    4.867
2               dt[, list(mean = mean(age), sd = sd(age)), by = group]   0.347    1.000
4   group_by(dtf, group) %>% summarise(mean = mean(age), sd = sd(age))   0.369    1.063
3    group_by(dt, group) %>% summarise(mean = mean(age), sd = sd(age))   0.580    1.671

මුලදී මම සිතුවේ ඔබ සෙට්කීව මිණුම් ලකුණට ගෙන යා යුතු බවයි, නමුත් ඒ සඳහා කිසිදු කාලයක් ගත නොවන බව පෙනේ.
කස්ටර්මා

10

පවත්නා යෝජනා වලට අමතරව, ඔබට පැකේජයේ describe.byක්‍රියාකාරිත්වය පරීක්ෂා කිරීමට අවශ්‍ය විය හැකිය psych.

එය කණ්ඩායම් විචල්‍යයක් මත පදනම් වූ මධ්‍යන්‍ය හා සම්මත අපගමනය ඇතුළු විස්තරාත්මක සංඛ්‍යාලේඛන ගණනාවක් සපයයි.


ලාටෙක්ස් IME වෙත අපනයනය කිරීමට එය කදිම, නමුත් තරමක් උපක්‍රමශීලී ය.
richiemorrisroe

10

මම කාර්යය සොයාගෙන ඇත summaryByතුළ doBy පැකේජය මේ සඳහා වඩාත්ම පහසු විය:

library(doBy)

age    = c(23.0883, 25.8344, 29.4648, 32.7858, 33.6372,
           34.935,  35.2115, 35.2115,  5.2115, 36.7803)
group  = c(1, 1, 1, 2, 1, 1, 2, 2, 2, 1)
dframe = data.frame(age=age, group=group)

summaryBy(age~group, data=dframe, FUN=c(mean, sd))
# 
#   group age.mean    age.sd
# 1     1 30.62333  5.415439
# 2     2 27.10507 14.640441

9

sqldfපැකේජය භාවිතා කරන්න . දත්ත සාරාංශ කිරීමට SQL භාවිතා කිරීමට මෙය ඔබට දැන් ඉඩ දෙයි. ඔබ එය පූරණය කළ පසු ඔබට එවැනි දෙයක් ලිවිය හැකිය -

sqldf('  select group,avg(age) from data group by group  ')

8

සංස්කරණය කළේ: chl ගේ යෝජනා අනුව

ඔබ සොයන ශ්‍රිතය "ටැප්ලි" ලෙස හැඳින්වෙන අතර එය සාධකයක් මගින් නිශ්චිතව දක්වා ඇති කණ්ඩායමකට ශ්‍රිතයක් අදාළ වේ.

# create some artificial data
set.seed(42)
groups <- 5

agedat <- c()
groupdat <- c()

for(group in 1:groups){
    agedat <- c(agedat,rnorm(100,mean=0 + group,1/group))
    groupdat <- c(groupdat,rep(group,100))
}
dat <- data.frame("age"=agedat,"group"=factor(groupdat))

# calculate mean and stdev age per group
res <- rbind.data.frame(group=1:5, with(dat, tapply(age, group, function(x) c(mean(x), sd(x)))))
names(res) <- paste("group",1:5)
row.names(res)[2:3] <- c("mean","sd")

බහුලව භාවිතා වන දත්ත ව්‍යුහයන් සහ ක්‍රම පැහැදිලි කරමින් මූලික R නිබන්ධනයක් හරහා වැඩ කිරීමට මම සැබවින්ම යෝජනා කරමි. එසේ නොමැතිනම් වැඩසටහන්කරණයේදී ඔබ සෑම අඟලක්ම හිර වනු ඇත. නොමිලේ ලබා ගත හැකි සම්පත් එකතුවක් සඳහා මෙම ප්‍රශ්නය බලන්න .


2
@steffen +1 නමුත් forමෙහි ලූපයක් අවශ්‍ය නොවේ , ඔබට ඔබේ දත්ත රාමු පේළිය, IMO සෑදිය හැකිය. OP විසින් සංඛ්‍යාලේඛන දෙකම ඉල්ලා ඇති පරිදි tapplyඇමතුම, භාවිතය function(x) c(mean(x),sd(x)))සහ cbindප්‍රති result ලය සඳහා. එසේම, ddplyඑම සිට plyr පැකේජය සියුම්ව මෙම කරන්න පුළුවන්.
chl

@steffen ගැටලුව වන්නේ මා විස්තර කළ වගු ව්‍යුහය මට අවශ්‍ය වීමයි. උපක්‍රම ලබා ගැනීමේ කිසිදු ගැටළුවක් නොමැත. ගැටළුව වන්නේ ව්‍යුහයයි.
යූරි පෙට්‍රොව්ස්කි

@chl: ඔබගේ අදහස් දැක්වීමට ස්තූතියි, ප්ලයර් ගැන දැන සිටියේ නැත :). මම cbind එකතු කළ නමුත් ඉතිරි ඒවා නොකියා සිටියෙමි. තවත් කෙනෙකුට ගෞරවය හිමි වේවා, මෙම පිළිතුර අඩු ප්‍රශස්ත උදාහරණයක් ලෙස පවතිනු ඇත.
ස්ටෙෆන්

Ur යූරි: එකතු කරන ලද cbind. කණ්ඩායමකට කාර්යයන් යෙදිය යුතු ආකාරය ඔබ දැනටමත් දැන සිටියේ නම්, ඔබට ඔබේ ප්‍රශ්නය නැවත සකස් කළ හැකිය (පැහැදිලිකම සඳහා;)).
ස්ටෙෆන්

@steffen cbind("mean"=mperage,"stdev"=stperage) gives no 'group' column. Will be joining by cbind (group = levels (factor (data $ group)), "mean" = mperage, "stdev" = stperage) `නිවැරදිද?
යූරි පෙට්‍රොව්ස්කි

7

aggregates()කලකට පෙර මා විසින්ම කරන ලද ශ්‍රිතය සමඟ උදාහරණයක් මෙන්න :

# simulates data
set.seed(666)
( dat <- data.frame(group=gl(3,6), level=factor(rep(c("A","B","C"), 6)), 
                    y=round(rnorm(18,10),1)) )

> dat
   group level    y
1      1     A 10.8
2      1     B 12.0
3      1     C  9.6
4      1     A 12.0
5      1     B  7.8
6      1     C 10.8
7      2     A  8.7
8      2     B  9.2
9      2     C  8.2
10     2     A 10.0
11     2     B 12.2
12     2     C  8.2
13     3     A 10.9
14     3     B  8.3
15     3     C 10.1
16     3     A  9.9
17     3     B 10.9
18     3     C 10.3

# aggregates() function
aggregates <- function(formula, data=NULL, FUNS){ 
    if(class(FUNS)=="list"){ 
        f <- function(x) sapply(FUNS, function(fun) fun(x)) 
    }else{f <- FUNS} 
    temp <- aggregate(formula, data, f) 
    out <- data.frame(temp[,-ncol(temp)], temp[,ncol(temp)]) 
    colnames(out)[1] <- colnames(temp)[1] 
return(out) 
} 

# example 
FUNS <- function(x) c(mean=round(mean(x),0), sd=round(sd(x), 0)) 
( ag <- aggregates(y~group:level, data=dat, FUNS=FUNS) ) 

එය පහත ප්‍රති result ලය ලබා දෙයි:

> ag
  group level mean sd
1     1     A   11  1
2     2     A    9  1
3     3     A   10  1
4     1     B   10  3
5     2     B   11  2
6     3     B   10  2
7     1     C   10  1
8     2     C    8  0
9     3     C   10  0

සමහර විට ඔබට R ශ්‍රිත බෙදීමෙන් () ආරම්භ වී එකම ප්‍රති result ලය ලබා ගත හැකිය:

> with(dat, sapply( split(y, group:level), FUNS ) )
     1:A 1:B 1:C 2:A 2:B 2:C 3:A 3:B 3:C
mean  11  10  10   9  11   8  10  10  10
sd     1   3   1   1   2   0   1   2   0

aggregatesශ්‍රිතයේ ප්‍රතිදානය වෙත නැවත පැමිණීමට මට ඉඩ දෙන්න . ඔබට එය භාවිතයෙන් අලංකාර වගුවකින් පරිවර්තනය කළ හැකිය reshape(), xtabs()සහ ftable():

rag <- reshape(ag, varying=list(3:4), direction="long", v.names="y") 
rag$time <- factor(rag$time) 
ft <- ftable(xtabs(y~group+level+time, data=rag)) 
attributes(ft)$col.vars <- list(c("mean","sd")) 

මෙය ලබා දෙන්නේ:

> ft 
             mean sd
group level         
1     A        11  1
      B        10  3
      C        10  1
2     A         9  1
      B        11  2
      C         8  0
3     A        10  1
      B        10  2
      C        10  0

ලස්සනයි නේද? පැකේජයේ textplot()ක්‍රියාකාරිත්වය සමඟ ඔබට මෙම වගුව පීඩීඑෆ් වෙත අපනයනය කළ හැකිය gplots.

අන් අයගේ විසඳුම් සඳහා මෙහි බලන්න .

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.