基于一个参考列与 dplyr 中其他列相比的摘要
Summaries based on one reference column compared to the other columns in dplyr
我想根据 R
中另一个变量的 na
或 non-na
值获取一个变量的总和。一个工作示例代码如下:
library(dplyr)
df <- data.frame(A = c(1,2,3,NA,4),
B = c(NA,2,3,NA,5),
C = c(3,4,NA,NA,NA),
REF = c(10,20,30,40,50))
df.na <- df %>% mutate_at(vars(-REF),is.na)
sums <- matrix(0,2,3)
row.names(sums) <- c("NON-NA","NA")
colnames(sums) <- c("A","B","C")
for(i in 1:3){
sums[,i] <- df.na %>% group_by_at(i) %>% summarise(sum=sum(REF)) %>% select(sum) %>% unlist()
}
> sums
A B C
NON-NA 110 100 30
NA 40 50 120
例如,由于 A
列中的第 4 项是 NA
,因此对应的列值是 sums
对象中的 30
和 10+20+3+50 = 150-30 = 120
。
我的问题是如何在没有 for 循环的情况下获得此输出?
这是一个使用 tidyr
中的 pivot_
函数的解决方案。该方法转向更长的形式,以便您可以按列名和列值是否为 NA 进行分组。
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = c("A", "B", "C")) %>%
mutate(isna = is.na(value)) %>%
group_by(name, isna) %>%
summarize(value = sum(REF)) %>%
pivot_wider()
isna A B C
<lgl> <dbl> <dbl> <dbl>
1 FALSE 110 100 30
2 TRUE 40 50 120
df <- data.frame(A = c(1,2,3,NA,4),
B = c(NA,2,3,NA,5),
C = c(3,4,NA,NA,NA),
REF = c(10,20,30,40,50))
library(tidyverse)
imap(.x = df[1:3],
.f = ~ df %>%
group_by(grp = is.na(.x)) %>%
summarise(!!.y := sum(REF, na.rm = T))) %>%
reduce(left_join)
#> Joining, by = "grp"
#> Joining, by = "grp"
#> # A tibble: 2 x 4
#> grp A B C
#> <lgl> <dbl> <dbl> <dbl>
#> 1 FALSE 110 100 30
#> 2 TRUE 40 50 120
由 reprex package (v2.0.1)
创建于 2022-01-26
我想根据 R
中另一个变量的 na
或 non-na
值获取一个变量的总和。一个工作示例代码如下:
library(dplyr)
df <- data.frame(A = c(1,2,3,NA,4),
B = c(NA,2,3,NA,5),
C = c(3,4,NA,NA,NA),
REF = c(10,20,30,40,50))
df.na <- df %>% mutate_at(vars(-REF),is.na)
sums <- matrix(0,2,3)
row.names(sums) <- c("NON-NA","NA")
colnames(sums) <- c("A","B","C")
for(i in 1:3){
sums[,i] <- df.na %>% group_by_at(i) %>% summarise(sum=sum(REF)) %>% select(sum) %>% unlist()
}
> sums
A B C
NON-NA 110 100 30
NA 40 50 120
例如,由于 A
列中的第 4 项是 NA
,因此对应的列值是 sums
对象中的 30
和 10+20+3+50 = 150-30 = 120
。
我的问题是如何在没有 for 循环的情况下获得此输出?
这是一个使用 tidyr
中的 pivot_
函数的解决方案。该方法转向更长的形式,以便您可以按列名和列值是否为 NA 进行分组。
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = c("A", "B", "C")) %>%
mutate(isna = is.na(value)) %>%
group_by(name, isna) %>%
summarize(value = sum(REF)) %>%
pivot_wider()
isna A B C
<lgl> <dbl> <dbl> <dbl>
1 FALSE 110 100 30
2 TRUE 40 50 120
df <- data.frame(A = c(1,2,3,NA,4),
B = c(NA,2,3,NA,5),
C = c(3,4,NA,NA,NA),
REF = c(10,20,30,40,50))
library(tidyverse)
imap(.x = df[1:3],
.f = ~ df %>%
group_by(grp = is.na(.x)) %>%
summarise(!!.y := sum(REF, na.rm = T))) %>%
reduce(left_join)
#> Joining, by = "grp"
#> Joining, by = "grp"
#> # A tibble: 2 x 4
#> grp A B C
#> <lgl> <dbl> <dbl> <dbl>
#> 1 FALSE 110 100 30
#> 2 TRUE 40 50 120
由 reprex package (v2.0.1)
创建于 2022-01-26