我有以下数据:
df <- structure(list(id = c("1358792", "1358792", "333482", "333482", "747475", "747475"),
x = c("123", "123", "456", "456", NA, NA),
all_x = list("123", "123",
c("456", "789"),
c("456", "789"),
list(),
list())),
row.names = c(NA, -6L),
class = "data.frame")
id x all_x
1 1358792 123 123
2 1358792 123 123
3 333482 456 456, 789
4 333482 456 456, 789
5 747475 <NA> NULL
6 747475 <NA> NULL
all_x 列是一个包含 EMPTY/NULL 值、单个字符或字符向量的列表。
我想创建一个新列(tidyverse 样式),其逻辑如下:当列all_x
有一个值或没有值时,只需从中取值x
。如果它有两个值(即字符向量),我们希望按id
行号分组并取对应的元素,即对于第一个 id 值,取字符向量的第一个元素,对于第二个 id 元素,取第二个字符值,依此类推。
所需的输出将是一个带有相应值的附加字符列,即
id x all_x x2
1 1358792 123 123 123
2 1358792 123 123 123
3 333482 456 456, 789 456
4 333482 456 456, 789 789
5 747475 <NA> NULL <NA>
6 747475 <NA> NULL <NA>
我已尝试过多种变体,包括if_else
,ifelse
以及取消列出和索引,但由于all_x
列的混合结构,仍然总是会出现错误。
以下是我得到的最接近的答案:
library(tidyverse)
df |>
mutate(x2 = if_else(lengths(all_x) > 1, all_x[[1]][row_number()], x), .by = id)
但是,显然,我没有成功。
x
这是一个函数,当有一个值或没有值时将返回all_x
,否则从all_x
对应于行号的元素中获取:然后这只是创建并使用的
row_number()
一个id
案例Map()
:我认为你应该使用
ifelse
(而不是if_else
),用最小的努力让它飞起来if_else
注意:和之间的区别ifelse
使用
NULL
总是有点笨拙,而且大多只在列表上下文中起作用。你可以NULL
用替换NA
,这样NULL
在非列表上下文中就不会出现任何问题