楼主: 卑鄙的我lzw
2348 10

[问答] 根据多个分组变量计算后再选取子集问题 [推广有奖]

  • 0关注
  • 4粉丝

硕士生

24%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
1.0000
学术水平
0 点
热心指数
1 点
信用等级
0 点
经验
1326 点
帖子
78
精华
0
在线时间
150 小时
注册时间
2017-7-18
最后登录
2021-5-10

楼主
卑鄙的我lzw 发表于 2019-1-9 19:47:41 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
各位各位,我有个问题想请大家帮帮忙~~~

我现在想通过两个分组变量(id和group),选取layer中 中间的三个观测,我想的是先通过分组变量id和group计算layer中的中位数,然后把中位数向上取整,然后中位数加1,中位数减1,就可以确定中间的三个观测了,但是怎么用代码实现啊{:2_38:}

我想通过① group_by(id,group) %>% median(layer) ,然后报错
             ②subset(test, layer == ceiling(median(layer)) | layer == ceiling(median(layer))+1 | layer == ceiling(median(layer))-1),但是没有用到分组变量啊!!!
             ③还有用data.table包:test[,layer == ceiling(median(layer)) | layer == ceiling(median(layer))+1 | layer == ceiling(median(layer))-1,by = list(group,id)] 出来的结果也是报错

好(;′⌒`)桑心蓝过啊,附上我的数据!!!! test.zip (254 Bytes) 本附件包括:
  • test.csv

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:ceiling median Subset Media Group

沙发
fyc7346165 发表于 2019-1-9 20:50:53
当layer的长度是奇数的时候,中间三个观测很好确定,例如长度是9时,中间三个观测即为从小到大排列后排名第4,5,6的观测
当layer的长度是偶数的时候,我这里暂且定为,例如长度是8时,中间三个观测为从小到大排列后排名第3,4,5的观测

那么下面就可以分组后取中间三个观测
  1. median3 <- function(x) {
  2.   mid <- ceiling(length(x) / 2)
  3.   pos <- c(mid-1, mid, mid+1)
  4.   x <- x[order(x)]
  5.   return(x[pos])
  6. }
  7. aggregate(data$layer, list(data$group, data$id), median3)
复制代码
已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
admin_kefu + 20 + 2 + 2 + 2 热心帮助其他会员

总评分: 论坛币 + 20  学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

藤椅
卑鄙的我lzw 发表于 2019-1-9 22:11:08
fyc7346165 发表于 2019-1-9 20:50
当layer的长度是奇数的时候,中间三个观测很好确定,例如长度是9时,中间三个观测即为从小到大排列后排名第 ...
嗯嗯,但是这样提取出来的Layer都被放到了变量x中,我想要的结果是如图排列的,这应该肿么办啊{:2_34:} outpput.png

板凳
caimiao0714 学生认证  发表于 2019-1-10 06:19:44
试试下面的代码

  1. set.seed(666)

  2. dat = data.frame(
  3.   id = sample(1:5, 200, replace = TRUE),
  4.   group = sample(1:5, 200, replace = TRUE),
  5.   layer = rnorm(200)
  6. )

  7. require(dplyr)

  8. dat %>% group_by(id, group) %>%
  9.   mutate(med = median(layer),
  10.          absdif = abs(layer - med)) %>%
  11.   arrange(id, group, absdif) %>%
  12.   filter(row_number() %in% 1:3) %>%
  13.   ungroup() %>%
  14.   select(id, group, layer)
复制代码
已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
admin_kefu + 30 + 2 + 2 + 2 热心帮助其他会员

总评分: 论坛币 + 30  学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

报纸
卑鄙的我lzw 发表于 2019-1-10 09:01:24
caimiao0714 发表于 2019-1-10 06:19
试试下面的代码
emmmm....我试了出来的不是我想要的结果,我的layer变量都是从1开始的整形变量。
而且我有两行代码不太明白,
一个是:absdif = abs(layer - med) 计算这个差值是为了什么啊?
另一个是:filter(row_number() %in% 1:3) 这是排序后选择前三行吗?有点不太懂····

地板
67890 发表于 2019-1-10 09:20:44
我的理解:
absdif = abs(layer - med): 计算每组的layer和中值的距离。
arrange(id, group, absdif): 用距离排序(升序)
filter(row_number() %in% 1:3): 取距离最小的前3
已有 1 人评分论坛币 学术水平 信用等级 收起 理由
admin_kefu + 30 + 2 + 2 热心帮助其他会员

总评分: 论坛币 + 30  学术水平 + 2  信用等级 + 2   查看全部评分

7
卑鄙的我lzw 发表于 2019-1-10 09:25:21
caimiao0714 发表于 2019-1-10 06:19
试试下面的代码
不过,受你的启发,我写出来啦,太感谢啦,么么扎
  1. data <- read.csv('test.csv')

  2. data %>% group_by(id, group) %>%
  3.   mutate(med = ceiling(median(layer)),
  4.          med1=med+1,
  5.          med2=med-1) %>%
  6.   filter(layer ==med | layer ==med1 | layer ==med2) %>%
  7.   ungroup() %>%
  8.   select(id, group, layer)
复制代码

8
卑鄙的我lzw 发表于 2019-1-10 11:26:24
67890 发表于 2019-1-10 09:20
我的理解:
absdif = abs(layer - med): 计算每组的layer和中值的距离。
arrange(id, group, absdif): 用 ...
原来如此,太感谢啦

9
caimiao0714 学生认证  发表于 2019-1-10 14:14:25
卑鄙的我lzw 发表于 2019-1-10 09:25
不过,受你的启发,我写出来啦,太感谢啦,么么扎
你的代码我直觉上是不对的,不过你能达到目的就好啦。

10
卑鄙的我lzw 发表于 2019-1-10 15:20:59
caimiao0714 发表于 2019-1-10 14:14
你的代码我直觉上是不对的,不过你能达到目的就好啦。
嘻嘻,我试过啦,咱们两个的代码跑出来的结果是一样的,但是我还是有点不明白:
filter(row_number() %in% 1:3)
这行代码是怎么运行的,为什么row_number()里不写参数啊,虽然用了管道连接符,那第一个参数dat不应该是给filter了吗?难道是同时给了filter和row_number吗?另外我单独运行了row_number出来的是colnames和好多NA,然后对colnames和好多NA进行了排序。

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

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