我有以下数据框(df):
PARTY_ID O1 O2 O3 O4
P1 20 NA NA NA
P2 3 18 NA NA
我需要用每行的最大值替换NA值。我想要的输出是:
PARTY_ID O1 O2 O3 O4
P1 20 20 20 20
P2 3 18 18 18
我需要快速执行此操作,因为我的数据有600K行。 有人可以帮帮我吗?
答案 0 :(得分:2)
使用tidyverse
&可以有多种选择reshape2
个包裹。
选项#1:您可以使用长格式转换数据并对其进行处理。最后使用dcast
将其转换回宽格式。
library(tidyverse)
library(reshape2)
df %>% gather(Key, Value, -PARTY_ID) %>%
group_by(PARTY_ID) %>%
mutate(Value = ifelse(is.na(Value), max(Value, na.rm = TRUE), Value)) %>%
dcast(PARTY_ID~Key, value.var = "Value")
# PARTY_ID O1 O2 O3 O4
# 1 P1 20 20 20 20
# 2 P2 3 18 18 18
选项#2: OP已经提到,因为她在data.frame中获得了巨大的行(600K
)。因此,另一种选择是以宽格式本身处理数据。 dplyr::mutate_at
在这种情况下会有很大的帮助。我更喜欢这个选项。
library(dplyr)
df %>% mutate(RowMax = apply(select(.,starts_with("O")), 1, FUN=max, na.rm=TRUE)) %>%
mutate_at(vars(starts_with("O")), funs(ifelse(is.na(.), RowMax,.))) %>%
select(-RowMax)
# PARTY_ID O1 O2 O3 O4
# 1 P1 20 20 20 20
# 2 P2 3 18 18 18
数据:强>
df <- read.table(text =
"PARTY_ID O1 O2 O3 O4
P1 20 NA NA NA
P2 3 18 NA NA",
header = TRUE, stringsAsFactors = FALSE)
答案 1 :(得分:1)
我没有可重复的数据集,但这可能有效:
t(apply(df_mat, 1, function(x) {ifelse(is.na(x), max(x, na.rm = TRUE), x)}))
答案 2 :(得分:1)
来自zoo
na.locf
data.frame(t(na.locf(t(A))))
PARTY_ID O1 O2 O3 O4
1 P1 20 20 20 20
2 P2 3 18 18 18
答案 3 :(得分:1)
这应该非常快,因为它是单个赋值而不是逐行:
idxna <- which(is.na(df[-1]), arr.ind=TRUE)
df[-1][idxna] <- do.call(pmax, c(df[-1], na.rm=TRUE))[idxna[,"row"]]
df
# PARTY_ID O1 O2 O3 O4
#1 P1 20 20 20 20
#2 P2 3 18 18 18
使用@ MKR的数据。