2017-06-15 14 views
5

Sütunların her bir öğeyi ne kadar satın alabileceklerini belirten müşterilere karşılık gelen sütun ve öğelere karşılık geldiği bazı anket verileri var. Bu gibi görünüyor:Veri çerçevesinin sütunları arasında frekans sayımları elde etmenin daha verimli bir yolu

item1 = c("Likely", "Unlikely", "Very Likely","Likely") 
item2 = c("Likely", "Unlikely", "Very Likely","Unlikely") 
item3 = c("Very Likely", "Unlikely", "Very Likely","Likely") 
df = data.frame(item1, item2, item3) 

ben her öğe için her tepki yüzdesini veren bir özet tablo istiyorum. Şu anda bu işlem için her sütunda tablo() kullanıyorum ve işlemek için çok fazla kod var. Bunu plyr kullanarak nasıl uygulayabilirim veya daha hızlı mı uygulayabilirim?

Güncel çözüm: Gerçekten frekans sayılarını, sadece yüzde gerekmez

d1<-as.data.frame(table(df$item1)) 
d1$item1_percent<- d1$Freq/sum(d1$Freq) 
names(d1)<-c("Response","item1_freqs","item1_percent") 

d2<-as.data.frame(table(df$item2)) 
d2$item2_percent<- d2$Freq/sum(d2$Freq) 
names(d2)<-c("Response","item2_freqs","item2_percent") 

d3<-as.data.frame(table(df$item3)) 
d3$item3_percent<- d3$Freq/sum(d3$Freq) 
names(d3)<-c("Response","item3_freqs","item3_percent") 

results<-cbind(d1,d2[,2:3],d3[,2:3]) 

Not.

Şimdiden teşekkürler!

+0

'lapply (df, function (x) prop.table (tablo (x))) – user20650

cevap

5

her öğe değerlerin aynı aralığı vardır gibi # Eğer

kullanabilirsiniz
sapply(df, function(x) prop.table(table(x))) 
#    item1 item2 item3 
# Likely  0.50 0.25 0.25 
# Unlikely  0.25 0.50 0.25 
# Very Likely 0.25 0.25 0.50 

Ama sen seviyeleri ortak bir dizi var her ürün no ayarlayabilirsiniz farklı olsaydı

df[] <- lapply(df, factor, levels=unique(unlist(df))) 
sapply(df, function(x) prop.table(table(x))) 
+0

Daha erken bir aşamada bunlarla başa çıkmaya çalışırsanız en kolay olurdu, 'read.table' set na 'yi kullanırken. string = c ("", ""). Veya bu boş değerleri "df [df ==" "] <- NA' ... – user20650

+1

olarak ayarlayabilirdiniz. Kendinizi lol üzgünüm. ama temelde ben veriyorum() (df, işlev (x) prop.table (tablo (x, exclude = ""))) benim veri boşlukları kontrol etmek için – SarahGC

+1

iyi şeyler. analizleri daha karmaşık hale geldikçe, daha erken bir aşamada, bu şeyleri daha iyi bir aşamada deneyimleyebilirsiniz. – user20650

2

dplyr kullanma:

results = data.frame(df %>% 
        group_by(item1) %>% 
          summarise(no_rows=length(item1)/nrow(df))) 
results = cbind(results, 
      data.frame(df %>% 
        group_by(item2) %>% 
          summarise(no_rows=length(item2)/nrow(df)))) 

results = cbind(results, 
      data.frame(df %>% 
        group_by(item3) %>% 
          summarise(no_rows=length(item3)/nrow(df)))) 


# > results 
#  item1 no_rows  item2 no_rows  item3 no_rows 
# 1  Likely 0.50  Likely 0.25  Likely 0.25 
# 2 Unlikely 0.25 Unlikely 0.50 Unlikely 0.25 
# 3 Very Likely 0.25 Very Likely 0.25 Very Likely 0.50 
+0

Teşekkürler! Çok yararlı. Yine de 3'ten fazla sütun var. "(Colnames (col) colnames (df)) {results = cbind (sonuç, data.frame (df%>% group_by (col) ..... " Daha iyi bir yol olmadığı sürece? – SarahGC

+0

Matt! Uygulamanın yararlı olabileceğini düşünmüyor musunuz cc: @SahaCummings – Masoud

2

lapply ile sayısına göre dataframe her sütunun içinden ilk döngü sonra Tepki üzerinde merge geçirilir dataframes bir liste oluşturmak için nerede zincir Reduce ile birleştirme düşünün:

dfList <- lapply(seq_along(df), function(i){  
    d <- as.data.frame(table(df[,i])) 
    d$item1_percent <- d$Freq/sum(d$Freq) 
    # PASS COLUMN NUMBER INTO DF COLUMN NAMES 
    names(d) <- c("Response", paste0("item",i,"_freqs"), paste0("item",i,"_percent")) 

    return(d)  
}) 

results2 <- Reduce(function(x,y) merge(x, y, by="Response", all.equal=TRUE), dfList) 

# EQUIVALENT TO ORIGINAL results 
all.equal(results, results2) 
# [1] TRUE 
identical(results, results2) 
# [1] TRUE 
2
Ben öğeleri farklı olmasına faktör seviyelerini, veri düzenleme farklı bir yol kullanmayı kullanarak öneririm

. Bu verilerle çalışmayı kolaylaştırır. o bir kerede iki paketi yükler beri tidyverse kitaplığı kullanarak Bunun için dplyr ve süpürge kullanılan

library(tidyverse) 

results <- df %>% 
gather("item", "likelihood") %>% 
group_by(item, likelihood) %>% 
summarise(n = n()) %>% 
mutate(freq = n/sum(n)) 

# > results 
# A tibble: 9 x 4 
# Groups: item [3] 
# item likelihood  n freq 
# <chr>  <chr> <int> <dbl> 
# 1 item1  Likely  2 0.50 
# 2 item1 Unlikely  1 0.25 
# 3 item1 Very Likely  1 0.25 
# 4 item2  Likely  1 0.25 
# 5 item2 Unlikely  2 0.50 
# 6 item2 Very Likely  1 0.25 
# 7 item3  Likely  1 0.25 
# 8 item3 Unlikely  1 0.25 
# 9 item3 Very Likely  2 0.50 

ama tercihim: Ben toplamak işlevini kullanarak verilerinizi dönüştürecek ve ardından frekans yüzdeleri hesaplamak için özetlemek kullanın .

Düzenleme: Eğer sütunlar olarak frekansları tutmak kullanmak istiyorsanız, bunu yapmanız yayılmış kullanabilirsiniz:

col_results <- results %>% 
    select(-n) %>% 
    spread(item, freq) 

# > col_results 
# A tibble: 3 x 4 
# likelihood item1 item2 item3 
# *  <chr> <dbl> <dbl> <dbl> 
# 1  Likely 0.50 0.25 0.25 
# 2 Unlikely 0.25 0.50 0.25 
# 3 Very Likely 0.25 0.25 0.50 
İlgili konular