【问题标题】:create dataframe of difference of medians in column based on values of another column根据另一列的值创建列中位数差异的数据框
【发布时间】:2021-08-21 04:54:43
【问题描述】:

我有一个如下所示的数据框:

data <- data.frame(id=c(1,2,6,3,7,1,5,7),
 class=c('apple','boy','boy','apple','boy','apple','apple','boy'), 
type=c('type1','type1','type2','type2','type3','type4','type4','type4'), 
col1=c(-0.9,0.8,0.7,-0.6,-0.5,0.4,0.3,0.9), col2=c(-6.9,2.8,0.4,-1.6,-0.8,0.6,0.2,-0.1), 
col3=c(6.7,0.9,0.2,-0.7,-0.8,1.6,3.2,0.1))

id class  type col1 col2 col3
1 apple type1 -0.9 -6.9  6.7
2   boy type1  0.8  2.8  0.9
6   boy type2  0.7  0.4  0.2
3 apple type2 -0.6 -1.6 -0.7
7   boy type3 -0.5 -0.8 -0.8
1 apple type4  0.4  0.6  1.6
5 apple type4  0.3  0.2  3.2
7   boy type4  0.9 -0.1  0.1

我正在尝试创建一个具有相同列(即 col1、col2、col3、...)的数据框,但其中的值应该是 median((data %&gt;% filter(class=="apple"))$col1) - median((data %&gt;% filter(class=="boy"))$col1),对于每列的每个 type,依此类推。

所以,最终的数据框看起来像

  type col1 col2 col3
type1 -0.1 -4.1  3.7
type2  0.7  0.4  0.2
type3 -0.5 -0.8 -0.8
type4  0.4  0.6  1.6

我可以通过为每个 type 创建单独的数据框并计算两个类的中位数的差异并将向量附加到带有 bind_rows() 的空数据框来做到这一点。

但是有没有更好更简单的方法来做到这一点?

【问题讨论】:

  • 您的示例代码(在段落中)有太多引号。如果我的回答不正确,那么请(a)修复您的代码错误,当语法 in the question 甚至无法解析时,可能很难解决编码问题/问题; (2) 扩展您的样本数据,以便您在每组中拥有多个观察值,因为单个数据的中位数相当无趣(并且与其本身的差异......不太那么:-)。
  • @kalki:请检查:median((data %&gt;% filter(class==""boy"))$col1) - median((data %&gt;% filter(class==""boy"))$col1)。这个对吗。给 0
  • @TarJae,我也看到了,可能是因为每组只有一个"boy",单个基准面的中位数就是基准面本身,然后从自身减去...就是@987654329 @.
  • @r2evans 感谢您指出错字。我已经编辑了帖子以修复它
  • 哦,是的,这是总结逻辑的一个重大变化。

标签: r dataframe


【解决方案1】:

你想要的方法是这样的:

data %>%
  group_by(type) %>%
  summarize(across(col1:col3, ~ median(.[class=="boy"] - median(.[class=="boy"]))))
# # A tibble: 4 x 4
#   type   col1  col2  col3
#   <chr> <dbl> <dbl> <dbl>
# 1 type1     0     0     0
# 2 type2     0     0     0
# 3 type3     0     0     0
# 4 type4     0     0     0

虽然在这种情况下它将返回所有 0s,因为每个组中只有一个 "boy"


发布问题-编辑,这是更新的代码和结果:

data %>%
 group_by(type) %>%
 summarize(across(col1:col3, ~ median(.[class=="apple"]) - median(.[class=="boy"])))
# # A tibble: 4 x 4
#   type     col1   col2    col3
#   <chr>   <dbl>  <dbl>   <dbl>
# 1 type1 -1.7    -9.700  5.8   
# 2 type2 -1.3000 -2     -0.9000
# 3 type3 NA      NA     NA     
# 4 type4 -0.55    0.5    2.3   

NAs 是因为type3 只有"boy",没有"apple"

(至少我们没有将"apple""orange" 进行比较,那将是陈词滥调;-)

【讨论】:

    【解决方案2】:

    这是获得解决方案的一种方法:这很难!

    library(dplyr)
    data %>% 
        arrange(id) %>% 
        filter(class == "boy" | type=="type1") %>% 
        group_by(type) %>% 
        summarise(across(starts_with("col"), sum))
    
      type   col1  col2  col3
      <chr> <dbl> <dbl> <dbl>
    1 type1  -0.1  -4.1   7.6
    2 type2   0.7   0.4   0.2
    3 type3  -0.5  -0.8  -0.8
    4 type4   0.9  -0.1   0.1
    

    【讨论】:

    • 您在示例代码中缺少一些括号,我认为是median(. - median(.))
    • TarJae,我在两个 cmets 和我的回答中都说了同样的话。您在“0”处的警报是正确的,这就是我们拥有的所有示例数据。
    • @TarJae 我已经纠正了我的问题,但这个解决方案仍然很有帮助。您能解释一下~ median(. - median(.)) 部分吗?这似乎类似于 r2evans 的回答。
    • (重新加载,7分钟前改过)
    • 嗯,好的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 2020-04-11
    相关资源
    最近更新 更多