楼主: liqian0614
21842 22

[问答] R中关于by函数的一个问题 [推广有奖]

11
bfdddp 发表于 2016-6-15 17:18:11

我也遇到了,仔细调试后发现by函数不能将数据框按照各列变量的顺序传送给dstats函数,结果dstats函数接受的是整个数据框3个变量一起算均数而报错,相反使用aggregate函数确没问题。估计是书作者版本和我们用的不同的原因,谁知道呢
> by(tt1[var],tt1[,1],dstats)
Error in is.data.frame(x) : (串列)对象不能强制改变成'double'种类
此外: Warning messages:
1: In mean.default(x) : 参数不是数值也不是逻辑值:回覆NA
2: In mean.default(x) : 参数不是数值也不是逻辑值:回覆NA
3: In mean.default(x) : 参数不是数值也不是逻辑值:回覆NA
> aggregate(tt1[var],by=list(sex=tt1[,2]),dstats)
  sex 年龄.mean   年龄.sd 空腹血糖.mean 空腹血糖.sd
1  男 64.333333 10.481730     6.8833333   1.6129683
2  女 54.000000  2.309401     5.5000000   0.5773503


> by(tt1[,4],tt1[,2],dstats)
tt1[, 2]: 男
    mean       sd
6.883333 1.612968
------------------------------------------------------------------------------------------------------------------
tt1[, 2]: 女
     mean        sd
5.5000000 0.5773503
> aggregate(tt1[4],by=list(sex=tt1[,2]),dstats)
  sex 空腹血糖.mean 空腹血糖.sd
1  男     6.8833333   1.6129683
2  女     5.5000000   0.5773503
> by(tt1[,3:4],tt1[,2],dstats)
Error in is.data.frame(x) : (串列)对象不能强制改变成'double'种类
此外: Warning message:
In mean.default(x) : 参数不是数值也不是逻辑值:回覆NA

我用的试验数据> tt1
   病历号 性别 年龄 空腹血糖
1       1   男   52      8.0
2       2   男   51      7.0
3       3   女   52      5.0
8       3   女   52      5.0
4       4   女   56      6.0
9       4   女   56      6.0
5       5   男   74      5.0
10      5   男   74      5.0
6       6   男   65      9.0
7       7   男   70      7.3
> str(tt1)
'data.frame':   10 obs. of  4 variables:
$ 病历号  : chr  "1" "2" "3" "3" ...
$ 性别    : Factor w/ 2 levels "男","女": 1 1 2 2 2 2 1 1 1 1
$ 年龄    : num  52 51 52 52 56 56 74 74 65 70
$ 空腹血糖: num  8 7 5 5 6 6 5 5 9 7.3
> var
[1] "年龄"     "空腹血糖"


我们版本 aggregate函数功能和作者的相比正好加强了,可以返回成组变量,by似乎能力变弱了达不到作者说的要求

12
xuesong_tang 发表于 2016-6-26 12:00:36
我也遇到这个问题了。算了,还是跳过去吧。 R里面的function又不是这一个,此路不通,换条路走走。

13
Sabergy 发表于 2016-7-7 17:53:36
有人解决了吗?纠结好久了

14
felixzhao123 发表于 2016-7-8 11:48:30
要想实现楼主要的结果,按照这种方式写代码效率太低,建议使用dplyr包来处理,代码如下:
  1. data(mtcars)
  2. require(dplyr)
  3. head(mtcars)
  4. mtcars_Summary <- mtcars%>%group_by(am)%>%
  5.   summarise(mpg_mean=mean(mpg),mpg_sd=sd(mpg))
  6. head(mtcars_Summary)
复制代码
已有 1 人评分论坛币 热心指数 收起 理由
admin_kefu + 20 + 2 热心帮助其他会员

总评分: 论坛币 + 20  热心指数 + 2   查看全部评分

15
hhq326781458 学生认证  发表于 2016-7-12 15:54:04
by(mtcars$mpg,mtcars$am,dstats)
mtcars$am: 0
     mean        sd
17.147368  3.833966
------------------------------------------------
mtcars$am: 1
     mean        sd
24.392308  6.166504


      我也是按照R实战书上不行,然后把数据框换成列表就行了,我用了mtcars$mpg试了下。说明 沙发 说的是对的呀,现在版本的R中mean和sd函数不能用于数据框。
      但是为什么aggregate函数可以呢,我没看help,但我估计aggregate函数里肯定自动把数据框按列分成一个个列表,然后再分别计算统计值。所以aggregate可以,by函数出错。
aggregate(mtcars[vars],by=list(am=mtcars$am),mean)
  am      mpg       hp       wt
1  0 17.14737 160.2632 3.768895
2  1 24.39231 126.8462 2.411000

已有 1 人评分论坛币 收起 理由
admin_kefu + 20 热心帮助其他会员

总评分: 论坛币 + 20   查看全部评分

16
hhq326781458 学生认证  发表于 2016-7-12 15:56:19
要是觉得答得可以。

17
稍等等 学生认证  发表于 2016-9-3 19:07:56
aggregate()函数可以一次性返回若干个统计量,R语言实战中的7-7改为aggregate可行,用这一个已经足够啦。

18
felton_cool 发表于 2016-9-23 11:25:26
> dstats <- function(x)(c(mean=mean(x), sd=sd(x)))
> aggregate(mtcars[vars], by = list(am=mtcars$am), dstats)
  am  mpg.mean    mpg.sd   hp.mean     hp.sd   wt.mean     wt.sd
1  0 17.147368  3.833966 160.26316  53.90820 3.7688947 0.7774001
2  1 24.392308  6.166504 126.84615  84.06232 2.4110000 0.6169816

19
felton_cool 发表于 2016-9-23 11:29:19
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

20
紫影潇潇 发表于 2017-5-27 17:07:11
felton_cool 发表于 2016-9-23 11:25
> dstats  aggregate(mtcars[vars], by = list(am=mtcars$am), dstats)
  am  mpg.mean    mpg.sd   hp.me ...
还真的是,aggregate可能新版升级了吧

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-25 12:59