用另一列的值替换属于一列的 NA
Replace NA's belonging to one column with values from another column
我有以下数据框(命名为 'df'),列名称为 ID、org1 和 org2。
结构:
ID org1 org2
1 C1 NA
2 C2 NA
3 C3 C3
4 C4 C4
5 C1 NA
6 NA C2
7 NA C4
8 NA NA
9 NA NA
10 C3 C3
现在,我希望 org1 从 org2 获取值,以防 org1 中的 'NA' 例如:ID 6
预期输出:
ID org1 org2
1 C1 NA
2 C2 NA
3 C3 C3
4 C4 C4
5 C1 NA
6 C2 C2
7 C4 C4
8 NA NA
9 NA NA
10 C3 C3
我厌倦了以下内容:
df$org1[is.na(df$org1)] <- as.character(df$org2[is.na(df$org1)])
参考如下:Replace NA in column with value in adjacent column
但这产生了以下错误:
Warning message:
In `[<-.factor`(`*tmp*`, is.na(df$org1), :invalid factor level, NA generated
谁能告诉我我做错了什么,有没有更好的解决方案。
通过使用 lapply
.
遍历 factor
列,将 factor
列转换为 character
class
df1[-1] <- lapply(df1[-1], as.character)
然后我们可以使用 pmax
。 pmax
将获取两列之间的按行最大元素。由于 'org2' 与 'org1' 几乎相同,除了 NA
值之外, pmax
和 na.rm=TRUE
在存在一个 NA 和非 NA 时删除 NA 元素-NA,或者如果有两个 NA return NA,或者两个非 NA 相同 return 唯一元素。
df1$org1 <- do.call(pmax, c(df1[-1], list(na.rm=TRUE)))
df1
# ID org1 org2
#1 1 C1 <NA>
#2 2 C2 <NA>
#3 3 C3 C3
#4 4 C4 C4
#5 5 C1 <NA>
#6 6 C2 C2
#7 7 C4 C4
#8 8 <NA> <NA>
#9 9 <NA> <NA>
#10 10 C3 C3
或者使用基于is.na
的逻辑索引,根据索引对'org1'进行子集,并用'org2'的对应元素替换。
ind <- is.na(df1$org1)
df1$org1[ind] <- df1$org2[ind]
或者正如@David Arenburg 在评论中提到的那样,我们可以 data.table
进行更快的分配。我们将 'data.frame' 转换为 'data.table' (setDT(df1)
),使用 'i' 中的逻辑条件,我们将 'org1' 赋值为 'org2' 对应'i'.
library(data.table)
setDT(df)[is.na(org1), org1 := org2]
数据
df1 <- structure(list(ID = 1:10, org1 = structure(c(1L, 2L, 3L, 4L,
1L, NA, NA, NA, NA, 3L), .Label = c("C1", "C2", "C3", "C4"),
class = "factor"),
org2 = structure(c(NA, NA, 2L, 3L, NA, 1L, 3L, NA, NA, 2L
), .Label = c("C2", "C3", "C4"), class = "factor")), .Names = c("ID",
"org1", "org2"), row.names = c(NA, -10L), class = "data.frame")
选项(stringsAsFactors =F) 会将所有列变成字符串(as.character)
options(stringsAsFactors = F)
mydf <- data.frame(ID = 1:10, org1 = c('C1','C2','C3','C4','C1',NA,NA,NA,NA,'C3'),
org2 = c(NA,NA,'C3','C4',NA,'C2','C4',NA,NA,'C3'))
mydf$org1[is.na(mydf$org1)] <- mydf$org2[is.na(mydf$org1)]
我有以下数据框(命名为 'df'),列名称为 ID、org1 和 org2。
结构:
ID org1 org2
1 C1 NA
2 C2 NA
3 C3 C3
4 C4 C4
5 C1 NA
6 NA C2
7 NA C4
8 NA NA
9 NA NA
10 C3 C3
现在,我希望 org1 从 org2 获取值,以防 org1 中的 'NA' 例如:ID 6
预期输出:
ID org1 org2
1 C1 NA
2 C2 NA
3 C3 C3
4 C4 C4
5 C1 NA
6 C2 C2
7 C4 C4
8 NA NA
9 NA NA
10 C3 C3
我厌倦了以下内容:
df$org1[is.na(df$org1)] <- as.character(df$org2[is.na(df$org1)])
参考如下:Replace NA in column with value in adjacent column
但这产生了以下错误:
Warning message:
In `[<-.factor`(`*tmp*`, is.na(df$org1), :invalid factor level, NA generated
谁能告诉我我做错了什么,有没有更好的解决方案。
通过使用 lapply
.
factor
列,将 factor
列转换为 character
class
df1[-1] <- lapply(df1[-1], as.character)
然后我们可以使用 pmax
。 pmax
将获取两列之间的按行最大元素。由于 'org2' 与 'org1' 几乎相同,除了 NA
值之外, pmax
和 na.rm=TRUE
在存在一个 NA 和非 NA 时删除 NA 元素-NA,或者如果有两个 NA return NA,或者两个非 NA 相同 return 唯一元素。
df1$org1 <- do.call(pmax, c(df1[-1], list(na.rm=TRUE)))
df1
# ID org1 org2
#1 1 C1 <NA>
#2 2 C2 <NA>
#3 3 C3 C3
#4 4 C4 C4
#5 5 C1 <NA>
#6 6 C2 C2
#7 7 C4 C4
#8 8 <NA> <NA>
#9 9 <NA> <NA>
#10 10 C3 C3
或者使用基于is.na
的逻辑索引,根据索引对'org1'进行子集,并用'org2'的对应元素替换。
ind <- is.na(df1$org1)
df1$org1[ind] <- df1$org2[ind]
或者正如@David Arenburg 在评论中提到的那样,我们可以 data.table
进行更快的分配。我们将 'data.frame' 转换为 'data.table' (setDT(df1)
),使用 'i' 中的逻辑条件,我们将 'org1' 赋值为 'org2' 对应'i'.
library(data.table)
setDT(df)[is.na(org1), org1 := org2]
数据
df1 <- structure(list(ID = 1:10, org1 = structure(c(1L, 2L, 3L, 4L,
1L, NA, NA, NA, NA, 3L), .Label = c("C1", "C2", "C3", "C4"),
class = "factor"),
org2 = structure(c(NA, NA, 2L, 3L, NA, 1L, 3L, NA, NA, 2L
), .Label = c("C2", "C3", "C4"), class = "factor")), .Names = c("ID",
"org1", "org2"), row.names = c(NA, -10L), class = "data.frame")
选项(stringsAsFactors =F) 会将所有列变成字符串(as.character)
options(stringsAsFactors = F)
mydf <- data.frame(ID = 1:10, org1 = c('C1','C2','C3','C4','C1',NA,NA,NA,NA,'C3'),
org2 = c(NA,NA,'C3','C4',NA,'C2','C4',NA,NA,'C3'))
mydf$org1[is.na(mydf$org1)] <- mydf$org2[is.na(mydf$org1)]