2017-04-24 139 views
1

我一直在嘗試自己並在網絡上搜索了一段時間,並且沒有成功。我有一個數據框,它是應用條件和選擇投影的子集,但無法檢索彙總輸出。使用聚合函數來計算數據框架中的輸出

數據幀mydf

mydf = list() 
mydf = cbind(mydf, 
      c("New York", "New York", "San Francisco"), 
      c(4000, 7600, 2500), 
      c("Bartosz", "Damian", "Maciej")) 
mydf = as.data.frame(mydf) 
colnames(mydf) = c("city","salary","name") 

假設給定的數據幀的一部分,與返回:

subset(mydf, city == "New York", select = c(salary, name)) 

它會返回一個數據幀,例如:

salary name 
9 4000 Bartosz 
10 7600 Damian 

現在我需要計算從給定的工資a sum,avg並選擇與來自上述數據幀,優選地使用一襯墊通過修改上面的代碼至少工資僱員(我猜測這是可能的),以便它返回:

sum:11600

avg :5800

爲至少4000巴爾託什


我試過的東西:(1)

subset(mydf, city == "New York", select = sum(salary)) 

或(2)

x = subset(mydf, city == "New York", select = salary) 
min(x) 

和許多組合,其僅產生錯誤說摘要函數僅與所有變量是一個數據幀上定義的數字(2)或相同的輸出作爲第一代碼,而無需sum(1)

回答

2

的問題可能是你的數據框對象實際上包含了一堆名單。所以,如果你把

ny.df = subset(mydf, city == "New York", select = c(salary, name)) 

那麼任何後續的工作需要與as.numeric調用來充塞你的列表轉化爲向量。這些會給你答案:

sum(as.numeric(ny.df$salary)) # sum 
mean(as.numeric(ny.df$salary)) # avg 
ny.df[which(as.numeric(ny.df$salary) == min(as.numeric(ny.df$salary))),] # row with min salary 

另外,可以定義mydf爲向量的數據幀,而不是列表的數據幀:

mydf = data.frame(c("New York", "New York", "San Francisco"), 
       c(4000, 7600, 2500), 
       c("Bartosz", "Damian", "Maciej")) 
colnames(mydf) = c("city","salary","name") 

ny.df = subset(mydf, city == "New York", select = c(salary, name)) 
sum(ny.df$salary) 
mean(ny.df$salary) 
ny.df[which(ny.df$salary == min(ny.df$salary)),] 
+1

謝謝你解釋爲什麼在這種情況下使用列表來構造數據框是一個不好的選擇。我決定重新整理我的數據框。 –

2

您的mydf很奇怪,所以我做了我自己的。我將mydf拆分爲city,然後從每個子組上運行必要的操作(平均值,總和等)中獲得必要的數據。

#DATA 
mydf = structure(list(city = structure(c(1L, 1L, 2L), .Label = c("New York", 
"San Francisco"), class = "factor"), salary = c(4000, 7600, 2500 
), name = structure(1:3, .Label = c("Bartosz", "Damian", "Maciej" 
), class = "factor")), .Names = c("city", "salary", "name"), row.names = c(NA, 
-3L), class = "data.frame") 

do.call(rbind, lapply(split(mydf, mydf$city), function(a) 
    data.frame(employee = a$name[which.min(a$salary)], #employee with least salary 
       mean = mean(a$salary), #mean salary 
       sum = sum(a$salary)))) #sum of salary 
#    employee mean sum 
#New York  Bartosz 5800 11600 
#San Francisco Maciej 2500 2500 
+1

首先,非常感謝把你的精力。我可能提供了誤導性的信息。我需要單獨的查詢來計算總和,平均值並選擇最小值。三個不同的電話。至於總和例如:只有總和工資作爲輸出。這個解釋更好嗎? –

+1

儘管如此,與我在@lebelinoz回答後提出的觀點相比,它看起來相當複雜。我不知道我的'mydf'是多麼奇怪。無論如何,+1努力,謝謝 –

+1

和你的幫助是非常感謝。如果你覺得不對,我表示歉意,不是那個意思。在需要時我肯定會使用這種方法。 –

1

您的數據框在數據框中非常規地列爲列表,這可能會造成您的問題。這裏是一個dplyr溶液(現在編輯找到個elowest工資)

library(dplyr) 
mydf <- data.frame(
      city = c("New York", "New York", "San Francisco"), 
      salary = c(4000, 7600, 2500), 
      name = c("Bartosz", "Damian", "Maciej")) 

mydf %>% 
    group_by(city) %>% 
    mutate(avg = mean(salary), 
     sum = sum(salary)) %>% 
    top_n(-1, wt = salary) 

#   city salary name avg sum 
#   <fctr> <dbl> <fctr> <dbl> <dbl> 
# 1  New York 4000 Bartosz 5800 11600 
# 2 San Francisco 2500 Maciej 2500 2500 
+0

對於初學者來說,非常感謝您付出的努力。我可能提供了誤導性的信息。我需要單獨的查詢來計算總和,平均值並選擇最小值。三個不同的電話。至於總和例如:只有總和工資作爲輸出。這個解釋更好嗎? –

1

我覺得dplyr是你可能是什麼尋找:

library(dplyr) 
    mydf %>% 
    group_by(city) %>% 
    filter (city =="New York") %>% 
    summarise(mean(salary), sum(salary)) 

    # A tibble: 1 x 3 
    # city mean(salary) sum(salary) 
    # <fctr>  <dbl>  <dbl> 
    #1 New York   5800  11600 

有一個在這個環節鏈接一個很好的教程[https://rpubs.com/justmarkham/dplyr-tutorial]

1

有使用data.table

library(data.table) 

setDT(mydf)[, .(salary_sum = sum(salary), 
       salary_avg = mean(salary), 
       name = name[which.min(salary)]), by= city] 

>    city salary_sum salary_avg name 
> 1:  New York  11600  5800 Bartosz 
> 2: San Francisco  2500  2500 Maciej 

數據集的簡單和快速的解決方案:

mydf = data.frame(city=c("New York", "New York", "San Francisco"), 
        salary=c(4000, 7600, 2500), 
        name=c("Bartosz", "Damian", "Maciej")) 
相關問題