Tambahkan perbedaan dan persen perubahan setiap kolom dalam bingkai data?

Saya ingin dapat menambahkan perbedaan dan persen perubahan ke setiap kolom dalam kerangka data.

Saya dapat menggabungkan data dan melakukan penghitungan, namun saya tidak tahu cara menyatukan atau membentuknya kembali. Saya juga curiga bahwa hal ini mudah dilakukan dengan plyr, tetapi baris n-1 yang dikembalikan oleh diff() memberi saya masalah.

Menggunakan kumpulan data yang disertakan:

library(plyr)
library(quantmod)
head(longley)

     GNP.deflator     GNP Unemployed Armed.Forces Population Year Employed
1947         83.0 234.289      235.6        159.0    107.608 1947   60.323
1948         88.5 259.426      232.5        145.6    108.632 1948   61.122
1949         88.2 258.054      368.2        161.6    109.773 1949   60.171
1950         89.5 284.599      335.1        165.0    110.929 1950   61.187
1951         96.2 328.975      209.9        309.9    112.075 1951   63.221
1952         98.1 346.999      193.2        359.4    113.270 1952   63.639

longley.m <- melt(longley, id="Year")
longley.m <- ddply(longley.m, .(variable), transform, valdiff=diff(c(NA, value)), valdelt=Delt(value))

head(longley.m)

  Year     variable value valdiff Delt.1.arithmetic
1 1947 GNP.deflator  83.0      NA                NA
2 1948 GNP.deflator  88.5     5.5       0.066265060
3 1949 GNP.deflator  88.2    -0.3      -0.003389831
4 1950 GNP.deflator  89.5     1.3       0.014739229
5 1951 GNP.deflator  96.2     6.7       0.074860335
6 1952 GNP.deflator  98.1     1.9       0.019750520

(Saya tidak tahu mengapa Delt membuat nama kolomnya sendiri, tapi saya sudah menyerah)

Sekarang, saya dapat cast(longley.m, Year ~ variable) kembali ke dataset asli, tetapi saya ingin dapat mengetahui selisih dan persentase perubahan untuk setiap variabel di kolom yang berbeda tanpa melakukan penghitungan secara manual pada setiap variabel lalu mengikatnya kembali. Saya cukup yakin saya telah mencoba setiap variasi pemeran tetapi tidak berhasil...

Pembaruan: Joran memecahkan masalah penamaan kolom Delt: memaksanya dengan as.vector!


person Totovader    schedule 01.01.2012    source sumber
comment
Benar? Masalah saya lebih pada melakukan operasi yang sama pada setiap kolom dan memasukkannya kembali ke dalam kerangka data. Saya tidak melihat solusi untuk itu di sana.   -  person Totovader    schedule 01.01.2012
comment
Saya kira saya tidak memahami sumber kesulitannya. Saya mengerti apa yang bisa saya lakukan untuk membatalkan suara.   -  person IRTFM    schedule 01.01.2012


Jawaban (3)


Saya mungkin akan melakukan pendekatan ini lebih seperti @joran.

Namun jika Anda ingin melanjutkan jalur yang Anda lalui, Anda dapat menggunakan reshape() dari basis R untuk menyelesaikan perjalanan:

# Your code
library(plyr)
library(quantmod)
library(reshape)
head(longley)
longley.m <- melt(longley, id="Year")

# My addition
longley.m <- ddply(longley.m, .(variable), transform, 
                   valdiff = diff(c(NA, value)), 
                   valdelt = as.vector(Delt(value)))
reshape(longley.m, idvar="Year", timevar="variable", direction="wide")
person Josh O'Brien    schedule 01.01.2012
comment
Saya pikir ini memberi saya apa yang saya cari. Pembentukan ulang tidak cocok bagi saya. Terima kasih! - person Totovader; 01.01.2012
comment
Hehe. Banyak orang memiliki pengalaman dengan reshape. - person IRTFM; 01.01.2012

Alasan nama kolom yang aneh saat menggunakan Delt adalah karena mengembalikan matriks, bukan vektor. Memaksanya dengan as.vector memecahkan misteri itu.

Namun, saya curiga Anda membuat ini terlalu rumit. Apakah ada alasan mengapa Anda tidak bisa begitu saja mengurutkan bingkai data berdasarkan tahun, lalu menerapkan diff dan Delt ke setiap kolom, mengganti nama kolom dengan tepat, lalu menggabungkannya cbind?

Beberapa kode awal:

longley.o <- arrange(longley,Year)
apply(longley.o,2,function(x){c(NA,diff(x))})
apply(longley.o,2,Delt)

Versi yang lebih lengkap (tidak perlu memasukkan kolom secara manual):

longley.o <- arrange(longley,Year)
valdiff <- apply(longley.o,2,function(x){c(NA,diff(x))})
valdelt <- apply(longley.o,2,Delt)

colnames(valdiff) <- paste("valdiff",colnames(valdiff),sep = ".")
colnames(valdelt) <- paste("valdelt",colnames(valdelt),sep = ".")

out <- cbind(longley.o,
             valdiff[,-match("Year",colnames(longley.o))],
             valdelt[,-match("Year",colnames(longley.o))])
person joran    schedule 01.01.2012
comment
Terima kasih telah memecahkan misteri pertama! Meskipun saya cenderung terlalu memperumit masalah, dalam hal ini saya merasa setidaknya saya berada di jalur yang benar. Masalah dengan hanya melakukan diff dan Delt pada setiap kolom (sebelum saya meleburnya) adalah saya menginginkannya setiap tahun untuk setiap variabel. Saya harus secara eksplisit memasukkan setiap kolom dalam solusi Anda. Masalah saya yang sebenarnya memiliki 20+ kolom di sekitar selusin kerangka data yang berbeda, jadi saya mencari jalan keluar yang mudah. - person Totovader; 01.01.2012
comment
@Totovader Saya tidak begitu mengikuti alasan Anda. Jika Anda lebih suka menggunakan pembentukan ulang, Josh siap membantu Anda. Pembaruan saya di atas akan memberikan hasil yang sama dengan jawabannya. - person joran; 01.01.2012
comment
Saya mengerti ke mana Anda pergi, sekarang- bagian kecocokan dari bagian cbind Anda asing bagi saya, jadi perlu beberapa langkah tambahan. - person Totovader; 01.01.2012
comment
Hati-hati menggunakan apply pada frame data - ini akan memaksa ke matriks. - person hadley; 01.01.2012

Saya pikir strategi peleburan dan kemudian pemrosesan dalam kategori suatu indikator merupakan hal yang rumit dan tidak perlu. Jika Anda menginginkan kerangka data dengan baris tambahan NA di awal sehingga cocok dengan nomor baris, maka ada dua alternatif yang disarankan sebagai satu baris:

as.data.frame( lapply(longley, function(x) c(NA, diff(x))))

Atau jika Anda tahu bahwa semua entri adalah numerik (seperti yang disarankan oleh penggunaan fungsi numerik) dan oleh karena itu boleh saja menggunakan apply maka pendekatan ini bahkan lebih sederhana:

apply(longley,2, FUN=function(x) c(NA, diff(x)))

Dan jika Anda ingin semua ini digabungkan dengan hasil Delt:

cbind(apply(longley,2, FUN=function(x) c(NA, diff(x))), 
      apply(longley,2, Delt) )
person IRTFM    schedule 01.01.2012