英文:
Fill across a data frame based on a value in a column in R
问题
我想要填充在y中指定的列数中m0中的值。期望的结果是:
y | m0 | m1 | m2 | mn |
---|---|---|---|---|
1 | 5 | 5 | NA | NA |
2 | 15 | 15 | 15 | NA |
3 | 25 | 25 | 25 | 25 |
感谢任何指导!
英文:
I have a data frame as below:
y | m0 | m1 | m2 | mn |
---|---|---|---|---|
1 | 5 | NA | NA | NA |
2 | 15 | NA | NA | NA |
3 | 25 | NA | NA | NA |
I would like to fill the value in m0 across the number of columns specified in y. Desired result is:
y | m0 | m1 | m2 | mn |
---|---|---|---|---|
1 | 5 | 5 | NA | NA |
2 | 15 | 15 | 15 | NA |
3 | 25 | 25 | 25 | 25 |
Appreciate any guidance!
答案1
得分: 1
你可以首先将你的数据转换成“长”格式,然后在NA
的计数在y
内时,用first
值替换NA
。
library(tidyverse)
df %>%
pivot_longer(-y) %>%
mutate(value = ifelse(is.na(value) & cumsum(is.na(value)) <= y, first(value), value),
.by = y) %>%
pivot_wider()
#> # A tibble: 3 × 5
#> y m0 m1 m2 mn
#> <int> <int> <int> <int> <int>
#> 1 1 5 5 NA NA
#> 2 2 15 15 15 NA
#> 3 3 25 25 25 25
请注意,这是R语言中的代码示例,用于将数据从宽格式转换为长格式,然后在特定条件下替换缺失值。
英文:
You can first transform your data to a "long" format, then replace NA
with the first
value when the count of NA
is within y
.
library(tidyverse)
df %>%
pivot_longer(-y) %>%
mutate(value = ifelse(is.na(value) & cumsum(is.na(value)) <= y, first(value), value),
.by = y) %>%
pivot_wider()
#> # A tibble: 3 × 5
#> y m0 m1 m2 mn
#> <int> <int> <int> <int> <int>
#> 1 1 5 5 NA NA
#> 2 2 15 15 15 NA
#> 3 3 25 25 25 25
答案2
得分: 1
A 基本 R 方法使用 sapply
。 colbeg
定义了第一个需要替换 NA 的列。可以硬编码,但我怀疑它应该可调整为真实数据。
colbeg <- 3
data.frame(t(sapply(seq_along(df$y), \(x){
df[x,colbeg:(colbeg - 1 + df$y[x])] <- df$m0[x]; df[x,]})))
y m0 m1 m2 mn
1 1 5 5 NA NA
2 2 15 15 15 NA
3 3 25 25 25 25
英文:
A base R approach using sapply
. colbeg
defines the first column where NA has to be replaced. Can be hard coded but I suspect that it should be adjustable for the real data.
colbeg <- 3
data.frame(t(sapply(seq_along(df$y), \(x){
df[x,colbeg:(colbeg - 1 + df$y[x])] <- df$m0[x]; df[x,]})))
y m0 m1 m2 mn
1 1 5 5 NA NA
2 2 15 15 15 NA
3 3 25 25 25 25
答案3
得分: 0
Base R:
```r
lapply(setNames(0:2, paste0("m", 0:2 + 1)), function(z) if (z < 1) quux$m0 else c(rep(NA, z), tail(quux$m0, n = -z))) |
as.data.frame()
# m1 m2 m3
# 1 5 NA NA
# 2 15 15 NA
# 3 25 25 25
You can either replace the columns or cbind them.
quux[,0:2 + 3] <- lapply(setNames(0:2, paste0("m", 0:2 + 1)), function(z) if (z < 1) quux$m0 else c(rep(NA, z), tail(quux$m0, n = -z))) |
as.data.frame()
quux <- cbind(
quux[,1:2],
lapply(setNames(0:2, paste0("m", 0:2 + 1)), function(z) if (z < 1) quux$m0 else c(rep(NA, z), tail(quux$m0, n = -z)))
)
(I'm consistently using 0:2
and offsets to show how things would be changed for an arbitrary number of columns.)
<details>
<summary>英文:</summary>
Base R:
```r
lapply(setNames(0:2, paste0("m", 0:2 + 1)), function(z) if (z < 1) quux$m0 else c(rep(NA, z), tail(quux$m0, n = -z))) |>
as.data.frame()
# m1 m2 m3
# 1 5 NA NA
# 2 15 15 NA
# 3 25 25 25
You can either replace the columns or cbind them.
quux[,0:2 + 3] <- lapply(setNames(0:2, paste0("m", 0:2 + 1)), function(z) if (z < 1) quux$m0 else c(rep(NA, z), tail(quux$m0, n = -z))) |>
as.data.frame()
quux <- cbind(
quux[,1:2],
lapply(setNames(0:2, paste0("m", 0:2 + 1)), function(z) if (z < 1) quux$m0 else c(rep(NA, z), tail(quux$m0, n = -z)))
)
(I'm consistently using 0:2
and offsets to show how things would be changed for an arbitrary number of columns.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论