لكل مجموعة تلخيص الوسائل لجميع المتغيرات في dataframe (ddply؟ينقسم؟)

StackOverflow https://stackoverflow.com/questions/1407449

  •  05-07-2019
  •  | 
  •  

سؤال

قبل أسبوع كنت سأفعل ذلك يدويًا:مجموعة بيانات فرعية حسب المجموعة إلى إطارات بيانات جديدة.بالنسبة لكل وسيلة حسابية لإطار البيانات لكل متغير، ثم rbind.متعجرف جدا ...

الآن تعلمت عن split و plyr, وأعتقد أنه يجب أن تكون هناك طريقة أسهل لاستخدام هذه الأدوات.من فضلك لا تثبت لي خطأ.

test_data <- data.frame(cbind(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T)))

test_data$var1 <- as.numeric(as.character(test_data$var1))
test_data$var2 <- as.numeric(as.character(test_data$var2))
test_data$var3 <- as.numeric(as.character(test_data$var3))
test_data$var4 <- as.numeric(as.character(test_data$var4))

أنا ألعب مع كليهما ddply لكني لا أستطيع إنتاج ما أرغب فيه - أي.جدول مثل هذا، لكل مجموعة

group a |2007|2009|
________|____|____|
var1    | xx | xx |
var2    | xx | xx |
etc.    | etc| ect|

ربما d_ply و البعض odfweave سيعمل الإخراج على.هي موضع تقدير كبير المدخلات.

ملاحظة.ألاحظ أن data.frame يحول المعيار إلى عوامل في data.frame الخاص بي؟كيف يمكنني تجنب ذلك - I(rnorm(100) لا يعمل لذا لا بد لي من التحويل إلى أرقام كما هو موضح أعلاه

هل كانت مفيدة؟

المحلول

وبالنظر إلى الشكل الذي تريده لنتيجة لذلك، فإن حزمة إعادة تشكيل تكون أكثر كفاءة من plyr.

test_data <- data.frame(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T))

library(reshape)
Molten <- melt(test_data, id.vars = c("group", "year"))
cast(group + variable ~ year, data = Molten, fun = mean)

والنتيجة تبدو مثل هذا

   group variable         2007         2009
1      a     var0  0.003767891  0.340989068
2      a     var1  2.009026385  1.162786943
3      a     var2  1.861061882  2.676524736
4      a     var3  2.998011426  3.311250399
5      a     var4  3.979255971  4.165715967
6      b     var0 -0.112883844 -0.179762343
7      b     var1  1.342447279  1.199554144
8      b     var2  2.486088196  1.767431740
9      b     var3  3.261451449  2.934903824
10     b     var4  3.489147597  3.076779626
11     c     var0  0.493591055 -0.113469315
12     c     var1  0.157424796 -0.186590644
13     c     var2  2.366594176  2.458204041
14     c     var3  3.485808031  2.817153628
15     c     var4  3.681576886  3.057915666
16     d     var0  0.360188789  1.205875725
17     d     var1  1.271541181  0.898973536
18     d     var2  1.824468264  1.944708165
19     d     var3  2.323315162  3.550719308
20     d     var4  3.852223640  4.647498956
21     e     var0 -0.556751465  0.273865769
22     e     var1  1.173899189  0.719520372
23     e     var2  1.935402724  2.046313047
24     e     var3  3.318669590  2.871462470
25     e     var4  4.374478734  4.522511874
26     f     var0 -0.258956555 -0.007729091
27     f     var1  1.424479454  1.175242755
28     f     var2  1.797948551  2.411030282
29     f     var3  3.083169793  3.324584667
30     f     var4  4.160641429  3.546527820
31     g     var0  0.189038036 -0.683028110
32     g     var1  0.429915866  0.827761101
33     g     var2  1.839982321  1.513104866
34     g     var3  3.106414330  2.755975622
35     g     var4  4.599340239  3.691478466
36     h     var0  0.015557352 -0.707257185
37     h     var1  0.933199148  1.037655156
38     h     var2  1.927442457  2.521369108
39     h     var3  3.246734239  3.703213646
40     h     var4  4.242387776  4.407960355
41     i     var0  0.885226638 -0.288221276
42     i     var1  1.216012653  1.502514588
43     i     var2  2.302815441  1.905731471
44     i     var3  2.026631277  2.836508446
45     i     var4  4.800676814  4.772964668
46     j     var0 -0.435661855  0.192703997
47     j     var1  0.836814185  0.394505861
48     j     var2  1.663523873  2.377640369
49     j     var3  3.489536343  3.457597835
50     j     var4  4.146020948  4.281599816

نصائح أخرى

ويمكنك القيام بذلك مع by(). أولا إعداد بعض البيانات:

R> set.seed(42)
R> testdf <- data.frame(var1=rnorm(100), var2=rnorm(100,2), var3=rnorm(100,3),  
                        group=as.factor(sample(letters[1:10],100,replace=T)),  
                        year=as.factor(sample(c(2007,2009),100,replace=T)))
R> summary(testdf)
      var1              var2              var3          group      year   
 Min.   :-2.9931   Min.   :-0.0247   Min.   :0.30   e      :15   2007:50  
 1st Qu.:-0.6167   1st Qu.: 1.4085   1st Qu.:2.29   c      :14   2009:50  
 Median : 0.0898   Median : 1.9307   Median :2.98   f      :12            
 Mean   : 0.0325   Mean   : 1.9125   Mean   :2.99   h      :12            
 3rd Qu.: 0.6616   3rd Qu.: 2.4618   3rd Qu.:3.65   d      :11            
 Max.   : 2.2866   Max.   : 4.7019   Max.   :5.46   b      :10            
                                                    (Other):26  

استخدم by():

R> by(testdf[,1:3], testdf$year, mean)
testdf$year: 2007
   var1    var2    var3 
0.04681 1.77638 3.00122 
--------------------------------------------------------------------- 
testdf$year: 2009
   var1    var2    var3 
0.01822 2.04865 2.97805 
R> by(testdf[,1:3], list(testdf$group, testdf$year), mean)  
## longer answer by group and year suppressed

وأنت لا تزال بحاجة إلى إعادة صياغة هذا الجدول الخاص بك ولكن لا تعطيك جوهر إجابتك في سطر واحد.

تحرير: مزيد من المعالجة كان يمكن أن يكون عن طريق

R> foo <- by(testdf[,1:3], list(testdf$group, testdf$year), mean)  
R> do.call(rbind, foo)
          var1   var2  var3
 [1,]  0.62352 0.2549 3.157
 [2,]  0.08867 1.8313 3.607
 [3,] -0.69093 2.5431 3.094
 [4,]  0.02792 2.8068 3.181
 [5,] -0.26423 1.3269 2.781
 [6,]  0.07119 1.9453 3.284
 [7,] -0.10438 2.1181 3.783
 [8,]  0.21147 1.6345 2.470
 [9,]  1.17986 1.6518 2.362
[10,] -0.42708 1.5683 3.144
[11,] -0.82681 1.9528 2.740
[12,] -0.27191 1.8333 3.090
[13,]  0.15854 2.2830 2.949
[14,]  0.16438 2.2455 3.100
[15,]  0.07489 2.1798 2.451
[16,] -0.03479 1.6800 3.099
[17,]  0.48082 1.8883 2.569
[18,]  0.32381 2.4015 3.332
[19,] -0.47319 1.5016 2.903
[20,]  0.11743 2.2645 3.452
R> do.call(rbind, dimnames(foo))
     [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]   [,10] 
[1,] "a"    "b"    "c"    "d"    "e"    "f"    "g"    "h"    "i"    "j"   
[2,] "2007" "2009" "2007" "2009" "2007" "2009" "2007" "2009" "2007" "2009"

ويمكنك ان تلعب مع dimnames بعض من المعلومات:

R> expand.grid(dimnames(foo))
   Var1 Var2
1     a 2007
2     b 2007
3     c 2007
4     d 2007
5     e 2007
6     f 2007
7     g 2007
8     h 2007
9     i 2007
10    j 2007
11    a 2009
12    b 2009
13    c 2009
14    d 2009
15    e 2009
16    f 2009
17    g 2009
18    h 2009
19    i 2009
20    j 2009
R> 

تحرير: ومع ذلك، ونحن يمكن أن تخلق data.frame للنتيجة دون اللجوء إلى الحزم الخارجية فقط باستخدام قاعدة R:

R> data.frame(cbind(expand.grid(dimnames(foo)), do.call(rbind, foo)))
   Var1 Var2     var1   var2  var3
1     a 2007  0.62352 0.2549 3.157
2     b 2007  0.08867 1.8313 3.607
3     c 2007 -0.69093 2.5431 3.094
4     d 2007  0.02792 2.8068 3.181
5     e 2007 -0.26423 1.3269 2.781
6     f 2007  0.07119 1.9453 3.284
7     g 2007 -0.10438 2.1181 3.783
8     h 2007  0.21147 1.6345 2.470
9     i 2007  1.17986 1.6518 2.362
10    j 2007 -0.42708 1.5683 3.144
11    a 2009 -0.82681 1.9528 2.740
12    b 2009 -0.27191 1.8333 3.090
13    c 2009  0.15854 2.2830 2.949
14    d 2009  0.16438 2.2455 3.100
15    e 2009  0.07489 2.1798 2.451
16    f 2009 -0.03479 1.6800 3.099
17    g 2009  0.48082 1.8883 2.569
18    h 2009  0.32381 2.4015 3.332
19    i 2009 -0.47319 1.5016 2.903
20    j 2009  0.11743 2.2645 3.452
R> 

يحرر: لقد كتبت ما يلي ثم أدركت أن تيري قد كتب بالفعل نفس الإجابة تقريبًا.لقد تجاهلت إجابته بطريقة أو بأخرى.لذا، إذا أعجبتك هذه الإجابة، قم بالتصويت لصالحه بدلاً من ذلك.سأمضي قدمًا وأقوم بالنشر منذ أن أمضيت الوقت في كتابته.


هذا النوع من الأشياء يستهلك من وقتي أكثر مما كنت أتمنى أن يفعل!إليك الحل باستخدام حزمة إعادة التشكيل بواسطة هادلي ويكهام.هذا المثال لا يفعل بالضبط ما طلبته لأن النتائج كلها في جدول واحد كبير، وليس جدولا لكل مجموعة.

كانت المشكلة التي كنت تواجهها مع ظهور القيم الرقمية كعوامل هي أنك كنت تستخدم cbind وكان كل شيء يتم ضربه في مصفوفة من نوع الحرف.الشيء الرائع هو أنك لا تحتاج إلى استخدام cbind مع data.frame.

test_data <- data.frame(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T))

library(reshape)
molten_data <- melt(test_data, id=c("group", "year")))
cast(molten_data, group + variable ~ year, mean)

وينتج عن ذلك ما يلي:

    group variable        2007         2009
1      a     var0 -0.92040686 -0.154746420
2      a     var1  1.06603832  0.559765035
3      a     var2  2.34476321  2.206521587
4      a     var3  3.01652065  3.256580166
5      a     var4  3.75256699  3.907777127
6      b     var0 -0.53207427 -0.149144766
7      b     var1  0.75677714  0.879387608
8      b     var2  2.41739521  1.224854891
9      b     var3  2.63877431  2.436837719
10     b     var4  3.69640598  4.439047363
...

كتبت أ مشاركة المدونة مؤخرًا حول القيام بشيء مماثل مع plyr.يجب أن أقوم بالجزء الثاني حول كيفية القيام بنفس الشيء باستخدام حزمة إعادة التشكيل.تمت كتابة كل من plyr وReshape بواسطة هادلي ويكهام، وهي أدوات مفيدة للغاية.

يمكن القيام بذلك باستخدام وظيفة R الأساسية:

n <- 100
test_data <- data.frame(
    var0 = rnorm(n),
    var1 = rnorm(n,1),
    var2 = rnorm(n,2),
    var3 = rnorm(n,3),
    var4 = rnorm(n,4),
    group = sample(letters[1:10],n,replace=TRUE),
    year = sample(c(2007,2009),n, replace=TRUE)
)

tapply(
    seq_len(nrow(test_data)),
    test_data$group,
    function(ind) sapply(
        c("var0","var1","var2","var3","var4"),
        function(x_name) tapply(
            test_data[[x_name]][ind],
            test_data$year[ind],
            mean
        )
    )
)

التفسيرات:

  • نصيحة:عندما يكون توليد بيانات عشوائية مفيدًا لتحديد عدد الملاحظات.تغيير حجم العينة أسهل بهذه الطريقة،
  • قم أولاً بتقسيم فهرس الصف 1:nrow(test_data) حسب المجموعات،
  • ثم لكل مجموعة تطبيق على المتغيرات
  • بالنسبة للمجموعة الثابتة والمتغير، قم بإجراء متوسط ​​إرجاع بسيط للمتغير في السنة.

في R 2.9.2 النتيجة هي:

$a
 var0.2007  var1.2007  var2.2007  var3.2007  var4.2007 
-0.3123034  0.8759787  1.9832617  2.7063034  4.1322758 

$b
            var0      var1     var2     var3     var4
2007  0.81366885 0.4189896 2.331256 3.073276 4.164639
2009 -0.08916257 1.5442126 3.008014 3.215019 4.398279

$c
          var0      var1     var2     var3     var4
2007 0.4232098 1.3657369 1.386627 2.808511 3.878809
2009 0.3245751 0.6672073 1.797886 1.752568 3.632318

$d
           var0      var1     var2     var3     var4
2007 -0.1335138 0.5925237 2.303543 3.293281 3.234386
2009  0.9547751 2.2111581 2.678878 2.845234 3.300512

$e
           var0      var1     var2     var3     var4
2007 -0.5958653 1.3535658 1.886918 3.036121 4.120889
2009  0.1372080 0.7215648 2.298064 3.186617 3.551147

$f
           var0      var1     var2     var3     var4
2007 -0.3401813 0.7883120 1.949329 2.811438 4.194481
2009  0.3012627 0.2702647 3.332480 3.480494 2.963951

$g
         var0       var1      var2     var3     var4
2007 1.225245 -0.3289711 0.7599302 2.903581 4.200023
2009 0.273858  0.2445733 1.7690299 2.620026 4.182050

$h
           var0     var1     var2     var3     var4
2007 -1.0126650 1.554403 2.220979 3.713874 3.924151
2009 -0.6187407 1.504297 1.321930 2.796882 4.179695

$i
            var0     var1     var2     var3     var4
2007  0.01697314 1.318965 1.794635 2.709925 2.899440
2009 -0.75790995 1.033483 2.363052 2.422679 3.863526

$j
           var0      var1     var2     var3     var4
2007 -0.7440600 1.6466291 2.020379 3.242770 3.727347
2009 -0.2842126 0.5450029 1.669964 2.747455 4.179531

مع بياناتي العشوائية، هناك مشكلة مع المجموعة "أ" - كانت هناك 2007 حالة فقط.إذا كانت السنة عاملاً (مع المستويات 2007 و2009)، فقد تبدو النتائج أفضل (سيكون لديك صفين لكل عام، ولكن من المحتمل أن يكون هناك NA).

النتيجة هي قائمة، لذا يمكنك استخدام lapply على سبيل المثال.تحويل إلى جدول اللاتكس، جدول HTML، الطباعة على الشاشة، وما إلى ذلك.

بادئ ذي بدء، لا تحتاج إلى استخدام cbind، ولهذا السبب كل شيء عامل.هذا يعمل:

test_data <- data.frame(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T))

ثانياً ، أفضل ممارسة هي استخدام ". بدلاً من "_" بأسماء متغيرة. راجع دليل أسلوب جوجل (على سبيل المثال).

وأخيرًا، يمكنك استخدام حزمة Rigroup؛انها سريعة جدا.ادمج الدالة igroupMeans() مع تطبيق وقم بتعيين الفهرس i=as.factor(paste(test_data$group,test_data$year,sep="")).سأحاول تضمين مثال على ذلك لاحقًا.

تحرير 6/9/2017

تمت إزالة حزمة Rigroup من CRAN.يرى هذا

وقيام الأولى مجرد تجميع للحصول عليه تلخيصها.

df <- aggregate(cbind(var0, var1, var2, var3, var4) ~ year + group, test_data, mean)

وهذا يجعل data.frame مثل هذا ...

   year group     var0      var1     var2     var3     var4
1  2007     a 42.25000 0.2031277 2.145394 2.801812 3.571999
2  2009     a 30.50000 1.2033653 1.475158 3.618023 4.127601
3  2007     b 52.60000 1.4564604 2.224850 3.053322 4.339109
...

وهذا، بحد ذاته، هو قريب جدا إلى ما تريد. هل يمكن أن مجرد الخروج عنه من قبل مجموعة الآن.

l <- split(df, df$group)

حسنا، هذا ليس تماما ولكن يمكننا تحسين الانتاج اذا كنت تريد حقا أن.

lapply(l, function(x) {d <- t(x[,3:7]); colnames(d) <- x[,2]; d})

$a
           2007      2009
var0 42.2500000 30.500000
var1  0.2031277  1.203365
var2  2.1453939  1.475158
...

وهذا لا يكون كل تنسيق الجدول الخاص بك ولكن هو تنظيم تماما كما تصفون، وهو قريب الرتق. هذه الخطوة الأخيرة التي يمكن أن تصل إلى حد كيف تشاء.

وهذا هو الحل الوحيد هنا الذي يتطابق مع منظمة المطلوبة، وانها أسرع طريقة للقيام بذلك في R. راجع للشغل، وأود أن لا يكلف نفسه عناء القيام بذلك الخطوة الأخيرة والعصا فقط مع الإخراج الأول جدا من مجموع المباراتين .. . أو ربما الانقسام.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top