我有这个数据框:
> df
X1 X2 X3 X4 X5 X6 X7
1 2 7 2 3 5 6 7
2 4 2 3 6 1 NA 3
3 3 6 4 4 4 7 7
4 6 5 6 NA 3 1 7
5 1 1 2 3 3 3 7
6 4 7 2 4 5 4 2
7 5 NA 4 5 2 2 3
8 3 7 2 4 4 1 5
9 4 5 6 2 5 6 3
10 2 4 6 4 5 6 3
我想计算数字1,2,3,4
并将其分配给x
,6,7
并将其分配给y
,并将所有数字(1,2,3,4,5,6,7)
分配给z
。之后,我将计算y/z - x/z
。
我已经用table(unlist(df))
并单独分配了值之后完成了此操作。但是,我正在寻找一种没有循环或apply()
的解决方案,因为我看不到升级它们的方法,因为我有近100列和10.000行(我知道它们都是从1开始的整数至7和NA values
)。
我正在寻找这样的解决方案:
x <- count(df, c(1,2,3,4), na.rm = TRUE)
y <- count(df, c(6,7), na.rm = TRUE)
z <- count(df, c(1,2,3,4,5,6,7), na.rm = TRUE)
但是,似乎count()
不能像那样工作,也不存在执行该操作的函数。
有什么建议吗?
答案 0 :(得分:4)
基本的R解决方案。
vec <- unlist(df)
vec_c <- table(vec)
x <- sum(vec_c[names(vec_c) %in% as.character(1:4)])
y <- sum(vec_c[names(vec_c) %in% as.character(6:7)])
z <- sum(vec_c)
y/z - x/z
# [1] -0.358209
另一个想法。
vec <- unlist(df)
x <- sum(vec %in% 1:4)
y <- sum(vec %in% 6:7)
z <- length(vec[!is.na(vec)])
y/z - x/z
# [1] -0.358209
另一个想法。
m <- as.matrix(df)
x <- sum(m %in% 1:4)
y <- sum(m %in% 6:7)
z <- sum(!is.na(df))
y/z - x/z
# [1] -0.358209
数据
df <- read.table(text = " X1 X2 X3 X4 X5 X6 X7
1 2 7 2 3 5 6 7
2 4 2 3 6 1 NA 3
3 3 6 4 4 4 7 7
4 6 5 6 NA 3 1 7
5 1 1 2 3 3 3 7
6 4 7 2 4 5 4 2
7 5 NA 4 5 2 2 3
8 3 7 2 4 4 1 5
9 4 5 6 2 5 6 3
10 2 4 6 4 5 6 3",
header = TRUE)
答案 1 :(得分:1)
这里是使用tidyverse
library(tidyverse)
gather(df, na.rm = TRUE) %>%
count(value) %>%
mutate(n1 = sum(n)) %>%
filter(value %in% c(1:4, 6:7)) %>%
group_by(grp = value %in% 1:4) %>%
summarise(perc = sum(n)/first(n1)) %>%
summarise(z = diff(perc))
# A tibble: 1 x 1
# z
# <dbl>
# 1 0.358
答案 2 :(得分:1)
另一种方法坚持使用table()
,将计数结构放入列表中。
count <- setNames(lapply(list(1:4, 6:7, 1:7), function(x){
tab <- table(unlist(d))
return(sum(tab[x]))
}), tail(letters, 3))
> with(count, y/z - x/z)
[1] -0.358209
数据
d <- structure(list(X1 = c(2L, 4L, 3L, 6L, 1L, 4L, 5L, 3L, 4L, 2L),
X2 = c(7L, 2L, 6L, 5L, 1L, 7L, NA, 7L, 5L, 4L), X3 = c(2L,
3L, 4L, 6L, 2L, 2L, 4L, 2L, 6L, 6L), X4 = c(3L, 6L, 4L, NA,
3L, 4L, 5L, 4L, 2L, 4L), X5 = c(5L, 1L, 4L, 3L, 3L, 5L, 2L,
4L, 5L, 5L), X6 = c(6L, NA, 7L, 1L, 3L, 4L, 2L, 1L, 6L, 6L
), X7 = c(7L, 3L, 7L, 7L, 7L, 2L, 3L, 5L, 3L, 3L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10"))