我有一个带有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
Run Code Online (Sandbox Code Playgroud)
我想为“ 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
Run Code Online (Sandbox Code Playgroud)
我想像这样将“ 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
Run Code Online (Sandbox Code Playgroud)
我尝试过的
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)]
Run Code Online (Sandbox Code Playgroud)
预期的data.table是:
> 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
Run Code Online (Sandbox Code Playgroud)
小智 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])
}
})
)
}
Run Code Online (Sandbox Code Playgroud)
说明:
我们可以从这样的列表中提取值:
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
Run Code Online (Sandbox Code Playgroud)
我们看到,如果没有值,我们就有一个NA.
我们需要一个迭代器来提取位置 处的所有值idx。为此,我们将找到df$c(列表)每个元素中的值的数量并保留最大值。
max(sapply(df$c, length))
[1] 3
Run Code Online (Sandbox Code Playgroud)
如果我们想要零而不是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
Run Code Online (Sandbox Code Playgroud)