2016-12-22 50 views
3

我有兩個列表:如何計算r中數據幀的特定子集和保存計算中的另一個列表

列表1:

id name age 
1 jake 21 
2 ashly 19 
45 lana 18 
51 james 23 
5675 eric 25 

表2(電視觀看):

id hours 
1 1.1 
1 3 
1 2.5 
45 5.6 
45 3 
51 2 
51 1 
51 2 

這只是一個例子,真正的列表非常大:列表1 - 5000的id,列表2/3/4 - 有超過100萬行(不是唯一的id)。

我需要爲每個列表2和以上計算每個id的平均值/總和/計數並將該值添加到列表1中。 請注意,我需要使用不同行號保存在另一個列表中的計算。

例如:

list 1: 
    id name age tv_average 
    1 jake 21 2.2 
    2 ashly 19 n/a 
    45 lana 18 4.3 
    51 james 23 1.6667 
    5675 eric 25 n/a 

這是我的嘗試:

for (i in 1:nrow(list2)) { 
    p <- subset(list2,list2$id==i) 
    list2$tv_average[i==list2$id] <- sum(p$hours)/(nrow(p)) 
} 

錯誤: 出來的22999行只在21713行工作。

+0

你需要在你的語言和共享數據更精確的重現性。這兩個對象看起來都是類'data.frame',它是一種特殊類型的'list'。 'subset()'可以在數據框上工作,但不能在列表上工作。如果您使用'dput()'或共享代碼來創建樣本數據,可重複共享數據,則這一切都將被清除。 [請閱讀此鏈接,瞭解如何製作出可重現的示例](http://stackoverflow.com/q/5963269/903061),然後編輯您的問題以使數據具有可重現性。 – Gregor

+0

如果您想嘗試更多的解決方案,看起來這是一個簡單的兩步過程。 1.爲列表2中的每個ID創建您的平均/總和/計數 - 請參閱常見問題[如何按組分組變量](http://stackoverflow.com/q/1660124/903061)。 2.將結果加入到列表1中 - 請參閱FAQ [如何在R中加入(合併)數據幀](http://stackoverflow.com/q/1299871/903061)。在這種情況下你想要一個左連接。 – Gregor

+0

您不必分享真實數據。您只需要使用'dput()'或共享代碼來創建樣本數據,就可以共享上面**可重複**的數據。 **請閱讀我的第一條評論**中的鏈接,瞭解相關情況。另外,正如我所說,*可能*你有數據框,而不僅僅是列表。並且子集在數據框架上工作良好。我無法確定,因爲你的數據不能被重複共享。 – Gregor

回答

2

試試這個

#Sample Data 
data1 = structure(list(id = c(1L, 2L, 45L, 51L, 5675L), name = structure(c(3L, 
1L, 5L, 4L, 2L), .Label = c("ashly", "eric", "jake", "james", 
"lana"), class = "factor"), age = c(21L, 19L, 18L, 23L, 25L) 
), .Names = c("id", 
"name", "age"), row.names = c(NA, -5L), class = "data.frame") 

data2 = structure(list(id = c(1L, 1L, 1L, 3L, 45L, 45L, 51L, 51L, 51L, 
53L), hours = c(1.1, 3, 2.5, 10, 5.6, 3, 2, 1, 2, 6)), .Names = c("id", 
"hours"), class = "data.frame", row.names = c(NA, -10L)) 

# Use aggregate to calculate Average, Sum, and Count and Merge 
merge(x = data1, 
     y = aggregate(hours~id, data2, function(x) 
      c(mean = mean(x), 
       sum = sum(x), 
       count = length(x))), 
     by = "id", 
     all.x = TRUE) 
# id name age hours.mean hours.sum hours.count 
#1 1 jake 21 2.200000 6.600000 3.000000 
#2 2 ashly 19   NA  NA   NA 
#3 45 lana 18 4.300000 8.600000 2.000000 
#4 51 james 23 1.666667 5.000000 3.000000 
#5 5675 eric 25   NA  NA   NA 
+0

使用'qdap'並逐個執行每一列來做最後的結果是不必要的。既然你已經在使用'plyr',只需要'data1 = plyr :: join(data1,tv_count)'。 「join」(左連接,加入常用列名)的默認值應該可以正常工作。或者你可以使用'base :: merge'。 – Gregor

+0

@allinr請在回答中附上你的代碼的解釋,這樣對未來的讀者會更有幫助。 – Barker