在 R 中使用带有嵌套 if 语句的 for 循环从数据框中的非 NA 值填充列
Use for loop with nested if statement in R to populate column from non-NA values in dataframe
我有 3 列数据要用于填充 D 列(下面的最终结果示例,当前 D 列为空白)。对于每一行,A-C 列将具有 1 个填充值和 2 个 NA 值。我该怎么做?
A B C D
1 'a' NA NA 'a'
2 NA 'b' NA 'b'
3 NA 'b' NA 'b'
4 NA NA 'c' 'c'
5 NA NA 'c' 'c'
6 'a' NA NA 'a'
7 'a' NA NA 'a'
8 NA NA 'c' 'c'
我尝试了以下函数,虽然它没有出错,但它没有填充我的数据集。我想知道我做错了什么。
感谢您的帮助
pop_D <- function(dataset){
for(i in 1:nrow(dataset)){
if(!is.na(dataset[i,'A'])){
dataset[i,'D'] <- dataset[i,'A']
}else if(!is.na(dataset[i,'B'])){
dataset[i,'D'] <- dataset[i,'B']
}else{
dataset[i,'D'] <- dataset[i,'C']
}
}
}
pop_D(ds)
我们可以使用pmax
来做到这一点
df1$D <- do.call(pmax, c(df1[1:3], na.rm = TRUE))
df1$D
#[1] "a" "b" "b" "c" "c" "a" "a" "c"
或者第二个选项是在 non-NA 元素的逻辑 matrix
上应用 max.col
以获得列索引,cbind
与行索引并提取元素基于这些指标
df1[1:3][cbind(1:nrow(df1), max.col(!is.na(df1[1:3]), 'first'))]
#[1] "a" "b" "b" "c" "c" "a" "a" "c"
作为对 akrun 答案的补充,如果您有一个矩阵(或您使用 as.matrix()
转换的数据框),您可以合并所有数据并省略所有 NA
创建变量 D,即
mt<-matrix(c("a",NA,NA,"a",NA,"b",NA,NA,NA,NA,"c",NA),ncol=3) #create test data
cbind(mt,na.omit(c(as.matrix(mt))))
考虑将 dft
作为您的输入,您可以使用 dplyr
并执行:
dft %>%
mutate(D = coalesce(A,B,C))
给出:
A B C D
1 a <NA> <NA> a
2 <NA> b <NA> b
3 <NA> b <NA> b
4 <NA> <NA> c c
5 <NA> <NA> c c
6 a <NA> <NA> a
7 a <NA> <NA> a
8 <NA> <NA> c c
p.s。我通过从问题中复制来准备示例输入数据:
dft <- read.table(header = TRUE, text = "id A B C D
1 'a' NA NA 'a'
2 NA 'b' NA 'b'
3 NA 'b' NA 'b'
4 NA NA 'c' 'c'
5 NA NA 'c' 'c'
6 'a' NA NA 'a'
7 'a' NA NA 'a'
8 NA NA 'c' 'c'",stringsAsFactors=FALSE)
dft$id<- NULL
dft$D <- NULL
我有 3 列数据要用于填充 D 列(下面的最终结果示例,当前 D 列为空白)。对于每一行,A-C 列将具有 1 个填充值和 2 个 NA 值。我该怎么做?
A B C D
1 'a' NA NA 'a'
2 NA 'b' NA 'b'
3 NA 'b' NA 'b'
4 NA NA 'c' 'c'
5 NA NA 'c' 'c'
6 'a' NA NA 'a'
7 'a' NA NA 'a'
8 NA NA 'c' 'c'
我尝试了以下函数,虽然它没有出错,但它没有填充我的数据集。我想知道我做错了什么。
感谢您的帮助
pop_D <- function(dataset){
for(i in 1:nrow(dataset)){
if(!is.na(dataset[i,'A'])){
dataset[i,'D'] <- dataset[i,'A']
}else if(!is.na(dataset[i,'B'])){
dataset[i,'D'] <- dataset[i,'B']
}else{
dataset[i,'D'] <- dataset[i,'C']
}
}
}
pop_D(ds)
我们可以使用pmax
来做到这一点
df1$D <- do.call(pmax, c(df1[1:3], na.rm = TRUE))
df1$D
#[1] "a" "b" "b" "c" "c" "a" "a" "c"
或者第二个选项是在 non-NA 元素的逻辑 matrix
上应用 max.col
以获得列索引,cbind
与行索引并提取元素基于这些指标
df1[1:3][cbind(1:nrow(df1), max.col(!is.na(df1[1:3]), 'first'))]
#[1] "a" "b" "b" "c" "c" "a" "a" "c"
作为对 akrun 答案的补充,如果您有一个矩阵(或您使用 as.matrix()
转换的数据框),您可以合并所有数据并省略所有 NA
创建变量 D,即
mt<-matrix(c("a",NA,NA,"a",NA,"b",NA,NA,NA,NA,"c",NA),ncol=3) #create test data
cbind(mt,na.omit(c(as.matrix(mt))))
考虑将 dft
作为您的输入,您可以使用 dplyr
并执行:
dft %>%
mutate(D = coalesce(A,B,C))
给出:
A B C D
1 a <NA> <NA> a
2 <NA> b <NA> b
3 <NA> b <NA> b
4 <NA> <NA> c c
5 <NA> <NA> c c
6 a <NA> <NA> a
7 a <NA> <NA> a
8 <NA> <NA> c c
p.s。我通过从问题中复制来准备示例输入数据:
dft <- read.table(header = TRUE, text = "id A B C D
1 'a' NA NA 'a'
2 NA 'b' NA 'b'
3 NA 'b' NA 'b'
4 NA NA 'c' 'c'
5 NA NA 'c' 'c'
6 'a' NA NA 'a'
7 'a' NA NA 'a'
8 NA NA 'c' 'c'",stringsAsFactors=FALSE)
dft$id<- NULL
dft$D <- NULL