If I have a data frame as follows:
如果我有一个数据框如下:
data.frame(
cola = c(3,NA,NA),
colb = c(1,NA,NA),
colc = c(NA,6,NA),
cold = c(NA,7,NA),
cole = c(NA,3,NA),
colf = c(NA,NA,9),
colg = c(NA,NA,8)
)
How can I shift all fields to the left, eliminating NA values as needed, as here:
如何将所有字段向左移动,根据需要消除NA值,如下所示:
data.frame(
cola = c(3,6,9),
colb = c(1,7,8),
colc = c(NA,3,NA)
)
Thanks for any help.
谢谢你的帮助。
3 个解决方案
#1
5
We loop through the rows, remove the NA
elements with na.omit
and then append NA
at the end based on the max length of the list
我们循环遍历行,用na.omit删除NA元素,然后根据列表的最大长度在末尾追加NA
lst <- apply(df1, 1, na.omit)
out <- as.data.frame(do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))))
#2
3
Another option could be:
另一种选择可能是:
library(tidyverse)
df %>% rownames_to_column() %>%
gather(measure, value, -rowname) %>%
group_by(rowname) %>%
na.omit() %>%
mutate(measure = paste0("col", row_number())) %>%
spread(measure, value) %>%
ungroup() %>%
select(-rowname)
# col1 col2 col3
# 1 3 1 NA
# 2 6 7 3
# 3 9 8 NA
#3
1
You can transpose, drop NAs, transpose back:
您可以转置,删除NAs,转置回:
library(magrittr)
library(data.table)
DF %>% transpose %>% lapply(na.omit) %>% transpose %>%
data.frame %>% setNames(names(DF)[seq_along(.)])
cola colb colc
1 3 1 NA
2 6 7 3
3 9 8 NA
#1
5
We loop through the rows, remove the NA
elements with na.omit
and then append NA
at the end based on the max length of the list
我们循环遍历行,用na.omit删除NA元素,然后根据列表的最大长度在末尾追加NA
lst <- apply(df1, 1, na.omit)
out <- as.data.frame(do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))))
#2
3
Another option could be:
另一种选择可能是:
library(tidyverse)
df %>% rownames_to_column() %>%
gather(measure, value, -rowname) %>%
group_by(rowname) %>%
na.omit() %>%
mutate(measure = paste0("col", row_number())) %>%
spread(measure, value) %>%
ungroup() %>%
select(-rowname)
# col1 col2 col3
# 1 3 1 NA
# 2 6 7 3
# 3 9 8 NA
#3
1
You can transpose, drop NAs, transpose back:
您可以转置,删除NAs,转置回:
library(magrittr)
library(data.table)
DF %>% transpose %>% lapply(na.omit) %>% transpose %>%
data.frame %>% setNames(names(DF)[seq_along(.)])
cola colb colc
1 3 1 NA
2 6 7 3
3 9 8 NA