我有以下数据框:
Source mean1 SD median range_min range_max IQR_25 IQR_75
1 1.5 0.2 3 NA NA NA NA
2 NA NA 2 1 5 1.5 4
3 NA NA 4 2 7 NA NA
我想根据特定条件将mean2
和FLAG
列添加到数据框中。条件如下:
1)如果存在mean1
和sd
,请将相同的值复制到mean2
列并为其提供FLAG ==1
2)如果mean1
和sd
为NA
但median:IQR_75
存在,则为mean2
设置等于20的值,并为其FLAG==2
}。注意:值20是任意的。我将改为使用等式,但这是为了使这里的问题变得容易。
3)如果mean1
和sd
为NA
但median, RANGE_min, RANGE_max
存在,则为mean2
设置等于30的值,并为其{{}} 1}}。
结果应如下所示:
FLAG==3
我尝试过以下操作,但使用它并没有太多运气:
Source mean1 SD median range_min range_max IQR_25 IQR_75 mean2 FLAG
1 1.5 0.2 3 NA NA NA NA 1.5 1
2 NA NA 2 1 5 1.5 4 20 2
3 NA NA 4 2 7 NA NA 30 3
我会请求你的帮助来实现我的目标,这样我就可以将它应用到我的大数据集上。
答案 0 :(得分:4)
使用data.table
包,您可以按照以下方式执行此操作:
library(data.table)
setDT(df)[!is.na(mean1) & !is.na(SD), `:=` (mean2 = mean1, Flag = 1)
][is.na(mean1) & is.na(SD) & complete.cases(median,range_min,range_max,IQR_25,IQR_75),
`:=` (mean2 = 20, Flag = 2)
][is.na(mean1) & is.na(SD) & complete.cases(median,range_min,range_max) & is.na(IQR_25) & is.na(IQR_75),
`:=` (mean2 = 30, Flag = 3)]
这给出了:
> df
Source mean1 SD median range_min range_max IQR_25 IQR_75 mean2 Flag
1: 1 1.5 0.2 3 NA NA NA NA 1.5 1
2: 2 NA NA 2 1 5 1.5 4 20.0 2
3: 3 NA NA 4 2 7 NA NA 30.0 3
或者,您可以事先为多个条件创建索引。这将提供更清晰的data.table
语法:
indx1 <- complete.cases(df[c("mean1", "SD")])
indx2 <- complete.cases(df[c("median","range_min","range_max","IQR_25","IQR_75")])
indx3 <- !complete.cases(df[c("IQR_25","IQR_75")]) & complete.cases(df[c("median","range_min","range_max")])
library(data.table)
setDT(df)[indx1, `:=` (mean2 = mean1, Flag = 1)
][!indx1 & indx2, `:=` (mean2 = 20, Flag = 2)
][!indx1 & indx3, `:=` (mean2 = 30, Flag = 3)]
答案 1 :(得分:2)
我们可以根据指定列中的NA元素创建几个逻辑索引。如果'mean1'和'SD'都不是NA,则'indx'给出TRUE,如果'median:IQR_75'列的行中没有NA值,则'indx2'将为TRUE,因为我们正在采用{{1} NA元素。类似地,'indx3'为列的中位数:range_max'的非NA元素赋予TRUE。
rowSums
现在我们可以通过算术运算创建一个数字索引,以创建一个唯一索引('indx4'),可用于填充值1.5,30,20或1:3。
indx <- rowSums(!is.na(df1[c('mean1', 'SD')]))==2
indx2 <- !rowSums(is.na(df1[4:ncol(df1)]))
indx3 <- !rowSums(is.na(df1[4:6]))
或者我们使用嵌套的 indx4 <- as.numeric(factor(1+2*indx+4*indx2+8*indx3))
c(1.5, 30, 20)[indx4]
#[1] 1.5 20.0 30.0
c(1,3,2)[indx4]
#[1] 1 2 3
ifelse
df1$mean2 <- ifelse(indx, 1.5, ifelse(indx2, 20, ifelse(indx3, 30, NA)))
df1$mean2
#[1] 1.5 20.0 30.0
df1$FLAG <- ifelse(indx, 1, ifelse(indx2, 2, ifelse(indx3, 3, NA)))
df1$FLAG
# [1] 1 2 3
df1
# Source mean1 SD median range_min range_max IQR_25 IQR_75 mean2 FLAG
#1 1 1.5 0.2 3 NA NA NA NA 1.5 1
#2 2 NA NA 2 1 5 1.5 4 20.0 2
#3 3 NA NA 4 2 7 NA NA 30.0 3
答案 2 :(得分:2)
试试这个:
df$mean2 = NA
df$FLAG = NA
ind1 = complete.cases(df[, c("mean1", "SD")])
ind2 = complete.cases(df[, c("median", "range_min", "range_max", "IQR_25", "IQR_75")])
ind3 = complete.cases(df[, c("median", "range_min", "range_max")])
df$mean2[ind1] = df$mean1[ind1]
df$mean2[!ind1 & ind2] = 20
df$mean2[!ind1 & !ind2 & ind3] = 30
df$FLAG[ind1] = 1
df$FLAG[!ind1 & ind2] = 2
df$FLAG[!ind1 & !ind2 & ind3] = 3