根据因子水平填充缺失的 NA
Filling in missing NA based upon factor level
我一直在尝试将我的数据从垂直配置转换为水平配置。使用 spread(),我设法得到了以下结构:
plot, x1, x2, x3, x4, x5, x6, x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA
7 rows
但是,显然我想用其他行的信息填充 NA。然后我的数据看起来像
plot , x1, x2, x3, x4, x5, x6, x7
1 0.06011071 0.09756118 -0.1422974NA 0.1809486 0.143701 0.1584451 0.1151581
我尝试了多种方法,但到目前为止都没有成功。有谁知道我怎样才能做到这一点?
是这样的吗?
df <- data.frame(x1 = c(1,NA,NA,NA,NA),
x2 = c(NA,2,NA,NA,NA),
x3 = c(NA,NA,3,NA,NA),
x4 = c(NA,NA,NA,4,NA),
x5 = c(NA,NA,NA,NA,5))
> df
x1 x2 x3 x4 x5
1 1 NA NA NA NA
2 NA 2 NA NA NA
3 NA NA 3 NA NA
4 NA NA NA 4 NA
5 NA NA NA NA 5
for (i in 1:ncol(df)){
df[,i][is.na(df[,i])] <- df[,i][!is.na(df[,i])]
}
> df
x1 x2 x3 x4 x5
1 1 2 3 4 5
2 1 2 3 4 5
3 1 2 3 4 5
4 1 2 3 4 5
5 1 2 3 4 5
这是使用 dplyr
的解决方案。它假定您希望为每个 plot
.
保留顶部的第一个非 NA 值
library(dplyr)
dat2 <- dat %>%
group_by(plot) %>%
summarize(
across(
everything(),
.fns = ~first(.x[!is.na(.x)])
)
) %>%
ungroup()
dat2
# # A tibble: 1 x 8
# plot x1 x2 x3 x4 x5 x6 x7
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
数据
dat <- read.table(text = "plot x1 x2 x3 x4 x5 x6 x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA",
header = TRUE)
或者:
library(tidyverse)
d <- read.table(text = "plot, x1, x2, x3, x4, x5, x6, x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA", header = TRUE)
d %>%
summarise(across(starts_with("x"), sum, na.rm = TRUE))
#x1. x2. x3. x4. x5. x6. x7
#1 0.06011071 0.09756118 -0.1422974 0.1809486 0.143701 0.1584451 0.1151581
我们也可以将na.omit
与dplyr一起使用:
df %>% group_by(plot) %>% summarise(across(matches('x\d+'), na.omit))
也许:
library(tidyverse)
df <- read.table(text = "plot, x1, x2, x3, x4, x5, x6, x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA", header = TRUE)
#if every column has only one value and the rest are NA's
tibble(plot = 1, map_dfc(df[, -1], ~.[!is.na(.)]))
#> # A tibble: 1 × 8
#> plot x1. x2. x3. x4. x5. x6. x7
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
#or gathering and spreading approach
pivot_longer(df,cols = matches('^x\d'), names_to = 'x') %>%
filter(!is.na(value)) %>%
arrange(x) %>%
pivot_wider(names_from = 'x', values_from = 'value')
#> # A tibble: 1 × 8
#> plot. x1. x2. x3. x4. x5. x6. x7
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
由 reprex package (v2.0.1)
于 2021-11-22 创建
我一直在尝试将我的数据从垂直配置转换为水平配置。使用 spread(),我设法得到了以下结构:
plot, x1, x2, x3, x4, x5, x6, x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA
7 rows
但是,显然我想用其他行的信息填充 NA。然后我的数据看起来像
plot , x1, x2, x3, x4, x5, x6, x7
1 0.06011071 0.09756118 -0.1422974NA 0.1809486 0.143701 0.1584451 0.1151581
我尝试了多种方法,但到目前为止都没有成功。有谁知道我怎样才能做到这一点?
是这样的吗?
df <- data.frame(x1 = c(1,NA,NA,NA,NA),
x2 = c(NA,2,NA,NA,NA),
x3 = c(NA,NA,3,NA,NA),
x4 = c(NA,NA,NA,4,NA),
x5 = c(NA,NA,NA,NA,5))
> df
x1 x2 x3 x4 x5
1 1 NA NA NA NA
2 NA 2 NA NA NA
3 NA NA 3 NA NA
4 NA NA NA 4 NA
5 NA NA NA NA 5
for (i in 1:ncol(df)){
df[,i][is.na(df[,i])] <- df[,i][!is.na(df[,i])]
}
> df
x1 x2 x3 x4 x5
1 1 2 3 4 5
2 1 2 3 4 5
3 1 2 3 4 5
4 1 2 3 4 5
5 1 2 3 4 5
这是使用 dplyr
的解决方案。它假定您希望为每个 plot
.
library(dplyr)
dat2 <- dat %>%
group_by(plot) %>%
summarize(
across(
everything(),
.fns = ~first(.x[!is.na(.x)])
)
) %>%
ungroup()
dat2
# # A tibble: 1 x 8
# plot x1 x2 x3 x4 x5 x6 x7
# <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
数据
dat <- read.table(text = "plot x1 x2 x3 x4 x5 x6 x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA",
header = TRUE)
或者:
library(tidyverse)
d <- read.table(text = "plot, x1, x2, x3, x4, x5, x6, x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA", header = TRUE)
d %>%
summarise(across(starts_with("x"), sum, na.rm = TRUE))
#x1. x2. x3. x4. x5. x6. x7
#1 0.06011071 0.09756118 -0.1422974 0.1809486 0.143701 0.1584451 0.1151581
我们也可以将na.omit
与dplyr一起使用:
df %>% group_by(plot) %>% summarise(across(matches('x\d+'), na.omit))
也许:
library(tidyverse)
df <- read.table(text = "plot, x1, x2, x3, x4, x5, x6, x7
1 0.06011071 NA NA NA NA NA NA
1 NA 0.09756118 NA NA NA NA NA
1 NA NA NA NA 0.143701 NA NA
1 NA NA NA NA NA 0.1584451 NA
1 NA NA NA 0.1809486 NA NA NA
1 NA NA NA NA NA NA 0.1151581
1 NA NA -0.1422974 NA NA NA NA", header = TRUE)
#if every column has only one value and the rest are NA's
tibble(plot = 1, map_dfc(df[, -1], ~.[!is.na(.)]))
#> # A tibble: 1 × 8
#> plot x1. x2. x3. x4. x5. x6. x7
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
#or gathering and spreading approach
pivot_longer(df,cols = matches('^x\d'), names_to = 'x') %>%
filter(!is.na(value)) %>%
arrange(x) %>%
pivot_wider(names_from = 'x', values_from = 'value')
#> # A tibble: 1 × 8
#> plot. x1. x2. x3. x4. x5. x6. x7
#> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
由 reprex package (v2.0.1)
于 2021-11-22 创建