我有一个带有list
列“ c”的data.table:
df <- data.table(a = 1:3, c = list(1L, 1:2, 1:3))
df
a c
1: 1 1
2: 2 1,2
3: 3 1,2,3
我想为“ c”中的值创建单独的列。
我创建了一组新列F_1,F_2,F_3:
mmax <- max(df$a)
flux <- paste("F", 1:mmax, sep = "_")
df[, (flux) := 0]
df
a c F_1 F_2 F_3
1: 1 1 0 0 0
2: 2 1,2 0 0 0
3: 3 1,2,3 0 0 0
我想像这样将“ c”中的值分派到F_1,F_2,F_3列:
df
a c F_1 F_2 F_3
1: 1 1 1 0 0
2: 2 1,2 1 2 0
3: 3 1,2,3 1 2 3
我尝试过的事情:
comp_vect <- function(vec, mmax){
vec <- vec %>% unlist()
n <- length(vec)
answr <- c(vec, rep(0, l = mmax -n))
}
df[ , ..flux := mapply(comp_vect, c, mmax)]
预期数据表为:
> df
a c F_1 F_2 F_3
1: 1 1 1 0 0
2: 2 1,2 1 2 0
3: 3 1,2,3 1 2 3
答案 0 :(得分:1)
解决方案:
for(idx in seq(max(sapply(df$c, length)))){ # maximum number of values according to all the elements of the list
set(x = df,
i = NULL,
j = paste0("F_",idx), # column's name
value = sapply(df$c, function(x){
if(is.na(x[idx])){
return(0) # 0 instead of NA
} else {
return(x[idx])
}
})
)
}
摘要:
我们可以从这样的列表中提取值:
sapply(df$c, function(ll) return(ll[1])) # first value
[1] 1 1 1
sapply(df$c, function(ll) return(ll[2])) # second value
[1] NA 2 2
sapply(df$c, function(ll) return(ll[3])) # third value
[1] NA NA 3
我们看到,如果没有价值,我们会有一个NA
。
我们需要一个迭代器来提取位置idx
上的所有值。为此,我们将在df$c
(列表)的每个元素中找到值的数量,并保持最大值。
max(sapply(df$c, length))
[1] 3
如果我们想要零而不是NAs
,则需要在sapply中创建一个函数来将它们转换:
vec <- c(NA, 5, 1, NA)
> sapply(vec, function(x) if(is.na(x)) return(0) else return(x))
[1] 0 5 1 0
答案 1 :(得分:1)
我采用了截然不同的方法。我rbind
编辑了列表列,然后dcast
对其进行了编辑,以获得所需的结果。最后一部分是设置名称。
library(data.table)
df <- data.table(a = 1:3, d = list(1L, c(1L, 2L), c(1L, 2L, 3L)))
df2 <- df[, rbind(d), by = a][, dcast(.SD, a ~ V1, fill = 0)]
setnames(df2, 2:4, flux)[]
a F_1 F_2 F_3
1: 1 1 0 0
2: 2 1 2 0
3: 3 1 2 3
其中flux
是您在问题中定义的名称的变量。
请注意,避免使用列名c
,因为它可能与函数c()
混淆。