用中位数替换 df 中的所有数字
Replace all numbers in a df by median
我想用行的中位数替换 df
中的所有数字,同时保持 NA 值。这是我的输入:
df <- 'pr_id sample1 sample2 sample3 median
AX-1 NA 120 130 125
AX-2 NA NA NA NA
AX-3 NA NA 196 196'
df <- read.table(text=df, header=T)
这是我的预期输出:
df <- 'pr_id sample1 sample2 sample3
AX-1 NA 125 125
AX-2 NA NA NA
AX-3 NA NA 196'
df <- read.table(text=df, header=T)
有实现该目标的想法吗?
使用dplyr你可以进行如下操作:
library(dplyr)
mutate_each(df, funs(ifelse(is.na(.), ., median)), sample1:sample3)
# pr_id sample1 sample2 sample3 median
#1 AX-1 NA 125 125 125
#2 AX-2 NA NA NA NA
#3 AX-3 NA NA 196 196
如果您想包括中位数计算,一种选择是转换为长格式,计算中位数,然后 re-convert 转换为宽格式:
library(tidyr)
gather(df, sample, value, sample1:sample3) %>%
group_by(pr_id) %>%
mutate(value = as.numeric(ifelse(is.na(value), value, median(value, na.rm = TRUE)))) %>%
spread(sample, value)
一个可能的基础解决方案
indx <- which(!is.na(df[-1]), arr.ind = TRUE) # find non-NA incidents
df[-1][indx] <- df$median[indx[, "row"]] # replace them while subsetting accordingly from df$median
df
# pr_id sample1 sample2 sample3 median
# 1 AX-1 NA 125 125 125
# 2 AX-2 NA NA NA NA
# 3 AX-3 NA NA 196 196
还有一个好处,如果您还没有中位数,这里有一种可能的方法可以即时计算它们
df[-1][indx] <- matrixStats::rowMedians(as.matrix(df[-1]), na.rm = TRUE)[indx[, "row"]]
纯数学:
cbind(df[1],NA^(is.na(df[,2:4]))*df$median)
# pr_id sample1 sample2 sample3
#1 AX-1 NA 125 125
#2 AX-2 NA NA NA
#3 AX-3 NA NA 196
如果需要计算中位数,只需将df$median
替换为apply(df[,2:4],1,median,na.rm=TRUE)
即可。
我想用行的中位数替换 df
中的所有数字,同时保持 NA 值。这是我的输入:
df <- 'pr_id sample1 sample2 sample3 median
AX-1 NA 120 130 125
AX-2 NA NA NA NA
AX-3 NA NA 196 196'
df <- read.table(text=df, header=T)
这是我的预期输出:
df <- 'pr_id sample1 sample2 sample3
AX-1 NA 125 125
AX-2 NA NA NA
AX-3 NA NA 196'
df <- read.table(text=df, header=T)
有实现该目标的想法吗?
使用dplyr你可以进行如下操作:
library(dplyr)
mutate_each(df, funs(ifelse(is.na(.), ., median)), sample1:sample3)
# pr_id sample1 sample2 sample3 median
#1 AX-1 NA 125 125 125
#2 AX-2 NA NA NA NA
#3 AX-3 NA NA 196 196
如果您想包括中位数计算,一种选择是转换为长格式,计算中位数,然后 re-convert 转换为宽格式:
library(tidyr)
gather(df, sample, value, sample1:sample3) %>%
group_by(pr_id) %>%
mutate(value = as.numeric(ifelse(is.na(value), value, median(value, na.rm = TRUE)))) %>%
spread(sample, value)
一个可能的基础解决方案
indx <- which(!is.na(df[-1]), arr.ind = TRUE) # find non-NA incidents
df[-1][indx] <- df$median[indx[, "row"]] # replace them while subsetting accordingly from df$median
df
# pr_id sample1 sample2 sample3 median
# 1 AX-1 NA 125 125 125
# 2 AX-2 NA NA NA NA
# 3 AX-3 NA NA 196 196
还有一个好处,如果您还没有中位数,这里有一种可能的方法可以即时计算它们
df[-1][indx] <- matrixStats::rowMedians(as.matrix(df[-1]), na.rm = TRUE)[indx[, "row"]]
纯数学:
cbind(df[1],NA^(is.na(df[,2:4]))*df$median)
# pr_id sample1 sample2 sample3
#1 AX-1 NA 125 125
#2 AX-2 NA NA NA
#3 AX-3 NA NA 196
如果需要计算中位数,只需将df$median
替换为apply(df[,2:4],1,median,na.rm=TRUE)
即可。