计算对数和平均值,将结果添加到R中的数据集中



在以下数据集中

code test1 ref1 test2 ref2
1    A  19.0 19.5  31.8   33
2    B  17.6 19.5  29.1   33
3    C  19.6 19.5  31.4   33
4    D  20.0 19.5  33.5   33
5    E  17.8 19.5  30.5   33
6    F  18.6 19.5  31.7   33
7    G  19.0 19.5  31.2   33
8    H  18.2 19.5  29.6   33
9    I  18.3 19.5  30.3   33

我想计算";测试";以及";ref";列。

log(test1)- log(ref1) = a
log(test2)- log(ref2) = b

然后,我想计算每行的a和b的平均值,并将结果保存在数据集中的新列上。

我试过这个功能:

f <- function(x) {
x[paste0(x, sep = "_log")] <<- log(x[x]) 
}
sapply(names(x)[-1], f)

但我只能计算每列的日志,并将结果添加到新列中。

如果我继续这样下去,我的数据集将太长。有人能帮我创建一个代码来执行所有计算并添加一列作为最终结果吗?

提前感谢

实际上,将数字paste添加到名称中是很酷的。这里有一个适合你的例子的解决方案。如果有四对,只需在sapply中使用1:4

rowMeans(sapply(1:2, (i) 
log(dat[[paste0('test', i)]]) - log(dat[[paste0('ref', i)]])), 
na.rm=TRUE)
# [1] -0.03150838 -0.11414248 -0.02229228  0.02017784 -0.08499844 -0.04372188
# [7] -0.04103248 -0.08886304 -0.07443663

注意:(i)在R4.1.0之前的R版本中表示function(i)

我们可以使用

library(dplyr)
df1 %>%
mutate(a = log(test1)- log(ref1), b = log(test2)- log(ref2),
Mean = rowMeans(cbind(a, b), na.rm = TRUE))

-输出

code test1 ref1 test2 ref2            a           b        Mean
1    A  19.0 19.5  31.8   33 -0.025975486 -0.03704127 -0.03150838
2    B  17.6 19.5  29.1   33 -0.102515564 -0.12576939 -0.11414248
3    C  19.6 19.5  31.4   33  0.005115101 -0.04969967 -0.02229228
4    D  20.0 19.5  33.5   33  0.025317808  0.01503788  0.02017784
5    E  17.8 19.5  30.5   33 -0.091216008 -0.07878088 -0.08499844
6    F  18.6 19.5  31.7   33 -0.047252885 -0.04019088 -0.04372188
7    G  19.0 19.5  31.2   33 -0.025975486 -0.05608947 -0.04103248
8    H  18.2 19.5  29.6   33 -0.068992871 -0.10873320 -0.08886304
9    I  18.3 19.5  30.3   33 -0.063513406 -0.08535985 -0.07443663

或者,如果有很多对,则自动执行

library(stringr)
df1 %>%
mutate(Mean = rowMeans(across(starts_with('test'), 
~ log(.) - log(get(str_replace(cur_column(), "test", "ref")))), na.rm = TRUE))

-输出

code test1 ref1 test2 ref2        Mean
1    A  19.0 19.5  31.8   33 -0.03150838
2    B  17.6 19.5  29.1   33 -0.11414248
3    C  19.6 19.5  31.4   33 -0.02229228
4    D  20.0 19.5  33.5   33  0.02017784
5    E  17.8 19.5  30.5   33 -0.08499844
6    F  18.6 19.5  31.7   33 -0.04372188
7    G  19.0 19.5  31.2   33 -0.04103248
8    H  18.2 19.5  29.6   33 -0.08886304
9    I  18.3 19.5  30.3   33 -0.07443663

数据

df1 <- structure(list(code = c("A", "B", "C", "D", "E", "F", "G", "H", 
"I"), test1 = c(19, 17.6, 19.6, 20, 17.8, 18.6, 19, 18.2, 18.3
), ref1 = c(19.5, 19.5, 19.5, 19.5, 19.5, 19.5, 19.5, 19.5, 19.5
), test2 = c(31.8, 29.1, 31.4, 33.5, 30.5, 31.7, 31.2, 29.6, 
30.3), ref2 = c(33L, 33L, 33L, 33L, 33L, 33L, 33L, 33L, 33L)),
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9"))

如果你经常用数据做这样的事情,你可能会发现把数据存储在"长";格式,因为这样的操作可以更自然地完成

制作成长格式

df1_long <- 
df1 %>% 
pivot_longer(names_pattern = '(test|ref)(\d+)',
names_to = c('name', 'num'),
cols = -1) %>% 
group_by(code, num) %>% 
arrange(name, .by_group = TRUE)
# # A tibble: 36 x 4
# # Groups:   code, num [18]
# code  name  num   value
# <chr> <chr> <chr> <dbl>
#   1 A     ref   1      19.5
#   2 A     test  1      19  
#   3 A     ref   2      33  
#   4 A     test  2      31.8
#   5 B     ref   1      19.5
#   6 B     test  1      17.6
#   7 B     ref   2      33  
#   8 B     test  2      29.1
#   9 C     ref   1      19.5
#   10 C     test  1      19.6
#   # … with 26 more rows

有了这种形状的数据,如何按组获得摘要就更明显了

df1_long %>% 
summarise(dlog = diff(log(value))) %>% 
summarise(mean_dlog = mean(dlog))
# # A tibble: 9 x 2
# code  mean_dlog
# <chr>     <dbl>
#   1 A       -0.0315
#   2 B       -0.114 
#   3 C       -0.0223
#   4 D        0.0202
#   5 E       -0.0850
#   6 F       -0.0437
#   7 G       -0.0410
#   8 H       -0.0889
#   9 I       -0.0744

你也可以使用这种方法,同时仍然保持数据的相同格式,但在这种情况下,你也可以在其他答案中使用这种方法

df1 %>% 
pivot_longer(names_pattern = '(test|ref)(\d+)',
names_to = c('name', 'num'),
cols = -1) %>% 
group_by(code, num) %>% 
arrange(name) %>% 
summarise(dlog = diff(log(value))) %>% 
summarise(mean_dlog = mean(dlog)) %>% 
mutate(.data = df1, mean_dlog = .$mean_dlog)
# code test1 ref1 test2 ref2   mean_dlog
# 1    A  19.0 19.5  31.8   33 -0.03150838
# 2    B  17.6 19.5  29.1   33 -0.11414248
# 3    C  19.6 19.5  31.4   33 -0.02229228
# 4    D  20.0 19.5  33.5   33  0.02017784
# 5    E  17.8 19.5  30.5   33 -0.08499844
# 6    F  18.6 19.5  31.7   33 -0.04372188
# 7    G  19.0 19.5  31.2   33 -0.04103248
# 8    H  18.2 19.5  29.6   33 -0.08886304
# 9    I  18.3 19.5  30.3   33 -0.07443663

最新更新