我有一个tibble
,其中包括一些列表列。
library(dplyr)
df <- structure(
list(ID = 1:5, V1 = list(1.71, -0.59, 0.73, -0.93, 0.18),
V2 = list(-0.08, c(0.59, 0.87), -1.87, -1.38, 0.83),
V3 = list(-0.25, -0.02, -0.97, -1.62, 0.54),
V4 = list(-0.12, 0.73, -0.36, 0.55, c(0.92, -0.49)),
V5 = list(c(-0.11, 0.14), -0.2, c(-1.12, -0.91), 0.14, c(1.56, 0.33))),
row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))
# # A tibble: 5 × 6
# ID V1 V2 V3 V4 V5
# <int> <list> <list> <list> <list> <list>
# 1 1 <dbl [1]> <dbl [1]> <dbl [1]> <dbl [1]> <dbl [2]>
# 2 2 <dbl [1]> <dbl [2]> <dbl [1]> <dbl [1]> <dbl [1]>
# 3 3 <dbl [1]> <dbl [1]> <dbl [1]> <dbl [1]> <dbl [2]>
# 4 4 <dbl [1]> <dbl [1]> <dbl [1]> <dbl [1]> <dbl [1]>
# 5 5 <dbl [1]> <dbl [1]> <dbl [1]> <dbl [2]> <dbl [2]>
我想将所有单元格长度为1的列表列(即V1
和V3
)简化为向量列。如果有任何单元格的编号大于1,则保持该列不变。预期输出如下:
# A tibble: 5 × 6
ID V1 V2 V3 V4 V5
<int> <dbl> <list> <dbl> <list> <list>
1 1 1.71 <dbl [1]> -0.25 <dbl [1]> <dbl [2]>
2 2 -0.59 <dbl [2]> -0.02 <dbl [1]> <dbl [1]>
3 3 0.73 <dbl [1]> -0.97 <dbl [1]> <dbl [2]>
4 4 -0.93 <dbl [1]> -1.62 <dbl [1]> <dbl [1]>
5 5 0.18 <dbl [1]> 0.54 <dbl [2]> <dbl [2]>
我已经用冗长的lapply()
和if
语句实现了它。我期待tidyverse
解决方案或简洁的base
解决方案。谢谢你的帮助。
您可以在across()
中使用where()
来确定哪些列表列的长度都为1。
library(dplyr)
df %>%
mutate(across(where(~ all(lengths(.x) == 1)), unlist))
# # A tibble: 5 × 6
# ID V1 V2 V3 V4 V5
# <int> <dbl> <list> <dbl> <list> <list>
# 1 1 1.71 <dbl [1]> -0.25 <dbl [1]> <dbl [2]>
# 2 2 -0.59 <dbl [2]> -0.02 <dbl [1]> <dbl [1]>
# 3 3 0.73 <dbl [1]> -0.97 <dbl [1]> <dbl [2]>
# 4 4 -0.93 <dbl [1]> -1.62 <dbl [1]> <dbl [1]>
# 5 5 0.18 <dbl [1]> 0.54 <dbl [2]> <dbl [2]>
基数R的解可以是,
i1 <- sapply(df, (i)all(lengths(i) == 1))
df[i1] <- lapply(df[i1], unlist)
df
# A tibble: 5 × 6
ID V1 V2 V3 V4 V5
<int> <dbl> <list> <dbl> <list> <list>
1 1 1.71 <dbl [1]> -0.25 <dbl [1]> <dbl [2]>
2 2 -0.59 <dbl [2]> -0.02 <dbl [1]> <dbl [1]>
3 3 0.73 <dbl [1]> -0.97 <dbl [1]> <dbl [2]>
4 4 -0.93 <dbl [1]> -1.62 <dbl [1]> <dbl [1]>
5 5 0.18 <dbl [1]> 0.54 <dbl [2]> <dbl [2]>