【问题标题】:R - how to count values over columns and divide by integers presentR - 如何计算列上的值并除以存在的整数
【发布时间】:2019-06-07 20:38:01
【问题描述】:

我有一个数据框,其中组的大小不同,但我想在新列中对行求和并除以 n(存在的整数数)(V1 .mean)

我们需要选择列号(在本例中为 [10:18]),除非有办法通过名称来完成。如果是这样,一定要教我,因为我必须像这样转换 8 个问题(x9)(参见下面的示例)。

所以我尝试了这个:

df$v1.mean <- rowSums(cbind(df[10:18]), na.rm = T ) / # sums it up
              ncol(is.integer(cbind(df[10:18] )))     # sums integers, but no

我看到了this dplyr 的例子,但我不确定如何让它在tally() 中工作

数据框看起来像这样,V1.mean是我正在寻找的解决方案。

  V1.1 V1.2 V1.3 V1.4 V1.5 V1.6 V1.7 V1.8  V1.9 V2.1 | V1.mean V2.mean
1     5    4    5   NA   NA   NA   NA   NA   NA   5  | 4.67 [== (5+4+5)/3]
2     5    5    5   NA   NA   NA   NA   NA   NA   3
3     5    5    5    5   NA   NA   NA   NA   NA  ...
4     5    4    5   NA   NA   NA   NA   NA   NA  ...
5     5    5   NA   NA   NA   NA   NA   NA   NA  ...
6     5    5    5    5   NA   NA   NA   NA   NA  ...
7     5    5    5    4    4   NA   NA   NA   NA  ...
8     5    5    5    4    5    5   NA   NA   NA  ... | 4.83 [== (5+5+5+4+5+5)/6]
9     4    5    5    5    4   NA   NA   NA   NA  ...
10    5    5    5   NA   NA   NA   NA   NA   NA  ...

提前致谢:)

【问题讨论】:

  • 你试过rowMeans(df, na.rm = TRUE)
  • rowMeans(df[grep('V1',names(df)], na.rm = TRUE)

标签: r dataframe dplyr tidyverse


【解决方案1】:

一个选项是将split 数据转换为data.frames 的listrowMeans

nm1 <- sub("\\.\\d+$", "", names(df1))
df1[paste0(unique(nm1), ".mean")] <- sapply(split.default(df1,
       sub("\\.\\d+$", "", names(df1))), rowMeans, na.rm = TRUE)

df1
#   V1.1 V1.2 V1.3 V1.4 V1.5 V1.6 V1.7 V1.8 V1.9 V2.1  V1.mean V2.mean
#1     5    4    5   NA   NA   NA   NA   NA   NA    5 4.666667       5
#2     5    5    5   NA   NA   NA   NA   NA   NA    3 5.000000       3
#3     5    5    5    5   NA   NA   NA   NA   NA    4 5.000000       4
#4     5    4    5   NA   NA   NA   NA   NA   NA    3 4.666667       3
#5     5    5   NA   NA   NA   NA   NA   NA   NA    2 5.000000       2
#6     5    5    5    5   NA   NA   NA   NA   NA    1 5.000000       1
#7     5    5    5    4    4   NA   NA   NA   NA    5 4.600000       5
#8     5    5    5    4    5    5   NA   NA   NA    4 4.833333       4
#9     4    5    5    5    4   NA   NA   NA   NA    1 4.600000       1
#10    5    5    5   NA   NA   NA   NA   NA   NA    5 5.000000       5

或者在 tidyverse 链中使用相同的逻辑

library(tidyverse)
df1 %>%
   split.default(nm1) %>%
   map_dfc(rowMeans, na.rm = TRUE) %>%
   rename_all(~ str_c(., ".mean")) %>% 
   bind_cols(df1, .)

数据

df1 <- structure(list(V1.1 = c(5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 4L, 5L
), V1.2 = c(4L, 5L, 5L, 4L, 5L, 5L, 5L, 5L, 5L, 5L), V1.3 = c(5L, 
5L, 5L, 5L, NA, 5L, 5L, 5L, 5L, 5L), V1.4 = c(NA, NA, 5L, NA, 
NA, 5L, 4L, 4L, 5L, NA), V1.5 = c(NA, NA, NA, NA, NA, NA, 4L, 
5L, 4L, NA), V1.6 = c(NA, NA, NA, NA, NA, NA, NA, 5L, NA, NA), 
    V1.7 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), V1.8 = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA), V1.9 = c(NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA), V2.1 = c(5L, 3L, 4L, 3L, 2L, 
    1L, 5L, 4L, 1L, 5L)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10"))

【讨论】:

  • 您的基本代码给出了正确的结果,但是您的 tidyverse 示例返回了此 Error in df1 %&gt;% split.default(nm1) %&gt;% map_dfc(rowMeans, na.rm = TRUE) %&gt;% : could not find function "%&gt;%"
  • @fleems 你加载了dplyrlibrary(dplyr)
  • 是的,我的 plyr 包运行在 @Wave 的评论中。
【解决方案2】:

Akrun 给出了正确答案,但对于大多数分析,您的数据并不是最简单的格式。

您可能需要考虑融合数据。

x = melt(as.matrix(df),varnames = c('row','col'))
x$id = substr(x$col,1,2)
ddply(x,c('row','id'),summarise,mean=mean(value,na.rm = T)) # or aggregate, etc.

【讨论】:

  • 感谢您的评论,如果我想在数据这样的情况下计算平均值,我通常会进行子集化和合并。它降低了给定代码行的复杂性,因为我必须共享脚本。我更喜欢留在 data.frame 中而不是将其转换为矩阵,但谢谢 :)
【解决方案3】:

我认为一个更简单的解决方案是来自hablarrow_mean。我重用了来自@akrun 的 df。

library(hablar)

df1 %>% 
  mutate(v1.mean = row_mean_(contains("v1")))

给你:

   V1.1 V1.2 V1.3 V1.4 V1.5 V1.6 V1.7 V1.8 V1.9 V2.1  v1.mean
1     5    4    5   NA   NA   NA   NA   NA   NA    5 4.666667
2     5    5    5   NA   NA   NA   NA   NA   NA    3 5.000000
3     5    5    5    5   NA   NA   NA   NA   NA    4 5.000000
4     5    4    5   NA   NA   NA   NA   NA   NA    3 4.666667
5     5    5   NA   NA   NA   NA   NA   NA   NA    2 5.000000
6     5    5    5    5   NA   NA   NA   NA   NA    1 5.000000
7     5    5    5    4    4   NA   NA   NA   NA    5 4.600000
8     5    5    5    4    5    5   NA   NA   NA    4 4.833333
9     4    5    5    5    4   NA   NA   NA   NA    1 4.600000
10    5    5    5   NA   NA   NA   NA   NA   NA    5 5.000000

【讨论】:

  • 哇,这很干净。感谢您的评论!
猜你喜欢
  • 2019-08-17
  • 2015-04-05
  • 2013-06-28
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多