计算R中具有NA值的行的平均值

时间:2014-03-17 15:36:50

标签: r

我有一个非常简单的R问题,但我似乎找不到合适的解决方案。假设我们有以下数据框:

groupid<-rep(1:5, each=3)
names<-rep(c("Bill", "Jim", "Sarah", "Mike", "Jennifer"),3)
test1<-rep(c(90, 70, 90, NA, 100),3)
test2<-rep(c(80, NA, 92, 80, 65), 3)
testscores<-data.frame(groupid, names, test1, test2)

groupid    names test1 test2

1        1     Bill    90    80
2        1      Jim    70    NA
3        1    Sarah    90    92
4        1     Mike    NA    80
5        1 Jennifer   100    65
6        2     Bill    90    80
7        2      Jim    70    NA
8        2    Sarah    90    92
9        2     Mike    NA    80
10       2 Jennifer   100    65
11       3     Bill    90    80
12       3      Jim    70    NA
13       3    Sarah    90    92
14       3     Mike    NA    80
15       3 Jennifer   100    65

我们感兴趣的是为每个测试获取跨行的平均值(向数据框添加额外的列),忽略NA值。例如,'Jim'的平均价值为70,而'Mike'的值为80.所有其他人的平均值都是正常的。

我尝试使用plyr包的转换,但它似乎不适应NA问题。

2 个答案:

答案 0 :(得分:2)

testscores$testMean <- rowMeans(testscores[,3:4], na.rm=TRUE)
> testscores
   groupid    names test1 test2 testMean
1        1     Bill    90    80     85.0
2        1      Jim    70    NA     70.0
3        1    Sarah    90    92     91.0
4        2     Mike    NA    80     80.0
5        2 Jennifer   100    65     82.5
6        2     Bill    90    80     85.0
7        3      Jim    70    NA     70.0
8        3    Sarah    90    92     91.0
9        3     Mike    NA    80     80.0
10       4 Jennifer   100    65     82.5
11       4     Bill    90    80     85.0
12       4      Jim    70    NA     70.0
13       5    Sarah    90    92     91.0
14       5     Mike    NA    80     80.0
15       5 Jennifer   100    65     82.5

答案 1 :(得分:2)

您也可以使用此

testscores <- structure(list(groupid = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 
4L, 4L, 4L, 5L, 5L, 5L), names = structure(c(1L, 3L, 5L, 4L, 
2L, 1L, 3L, 5L, 4L, 2L, 1L, 3L, 5L, 4L, 2L), .Label = c("Bill", 
"Jennifer", "Jim", "Mike", "Sarah"), class = "factor"), test1 = c(90, 
70, 90, NA, 100, 90, 70, 90, NA, 100, 90, 70, 90, NA, 100), test2 = c(80, 
NA, 92, 80, 65, 80, NA, 92, 80, 65, 80, NA, 92, 80, 65)), .Names = c("groupid", 
"names", "test1", "test2"), row.names = c(NA, -15L), class = "data.frame")

testscores$meanTest=rowMeans(testscores[,c("test1", "test2")], na.rm=TRUE)

#   groupid    names test1 test2 meanTest
#1        1     Bill    90    80     85.0
#2        1      Jim    70    NA     70.0
#3        1    Sarah    90    92     91.0
#4        2     Mike    NA    80     80.0
#5        2 Jennifer   100    65     82.5
#6        2     Bill    90    80     85.0
#7        3      Jim    70    NA     70.0
#8        3    Sarah    90    92     91.0
#9        3     Mike    NA    80     80.0
#10       4 Jennifer   100    65     82.5
#11       4     Bill    90    80     85.0
#12       4      Jim    70    NA     70.0
#13       5    Sarah    90    92     91.0
#14       5     Mike    NA    80     80.0
#15       5 Jennifer   100    65     82.5