我正在为以下任务寻求一个解决方案。我有一个数据框,其中包含一个变量,该变量是具有属性dimnames的列表列表。这些清单有不同的长度。这是str(df)
的输出:
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 3 obs. of 2 variables:
$ Step : int 1 2 3
$ Value:List of 3
..$ : num [1:2, 1:2] 0.232 0.261 0.932 0.875
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr "4" "5"
.. .. ..$ : chr "0.2" "0.094"
..$ : num [1:2, 1:5] 0.197 0.197 0.64 0.643 0.958 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr "4" "5"
.. .. ..$ : chr "0.2" "0.094" "0.044" "0.021" ...
..$ : num [1:2, 1] 0.268 0.262
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr "4" "5"
.. .. ..$ : chr "0.2"
我已在下方添加了dput代码以重新创建此数据帧。
我想要一个以下格式的数据框:
Step Value a b
1 0.232 4 0.200
1 0.261 5 0.200
1 0.932 4 0.094
1 0.875 5 0.094
1 NA 4 0.044
1 NA 5 0.044
1 NA 4 0.021
1 NA 5 0.021
1 NA 4 0.010
1 NA 5 0.010
2 0.197 4 0.200
2 0.197 5 0.200
2 0.640 4 0.094
2 0.643 5 0.094
2 0.958 4 0.044
2 1.032 5 0.044
2 0.943 4 0.021
2 1.119 5 0.021
2 0.943 4 0.010
2 1.119 5 0.010
3 0.268 4 0.200
3 0.262 5 0.200
3 NA 4 0.094
3 NA 5 0.094
3 NA 4 0.044
3 NA 5 0.044
3 NA 4 0.021
3 NA 5 0.021
3 NA 4 0.010
3 NA 5 0.010
其中变量a
是列表名称dimnames的行名称,b
是列名称。
我已尝试for
循环逐步分离每个列表,但
1)我没有成功填写NA
s(length(x) <- y
无效)列表。
2)我已经审核了advanced R data types,但未成功将dimnames提取到矢量中以用作数据帧列(attr(df$Value, "dimnames")
会产生NULL
。)< / p>
一旦我有相同长度的列表,我就可以在for
循环中逐步构建新的数据帧向量,然后再建立rbind。或者有没有办法使用dimname属性直接构造一个宽的数据帧使用行和列dimnames作为数据帧列名?然后我可以gather
制作一个长数据帧。
这里有几个子问题,我确信这是一个比我已经绘制出来的解决方案更优雅的解决方案。谢谢你的期待。
这是创建数据帧的dput代码:
df <- structure(list(Step = c(1L, 2L, 3L), Value = list(structure(c(0.232,
0.261, 0.932, 0.875), .Dim = c(2L,
2L), .Dimnames = list(c("4", "5"), c("0.2", "0.094"
))), structure(c(0.197, 0.197, 0.640,
0.643, 0.958, 1.032, 0.943,
1.119, 0.943, 1.119), .Dim = c(2L,
5L), .Dimnames = list(c("4", "5"), c("0.2", "0.094",
"0.044", "0.021", "0.01"))), structure(c(0.268,
0.262), .Dim = c(2L, 1L), .Dimnames = list(c("4",
"5"), "0.2")))), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-3L), .Names = c("Step", "Value"))
答案 0 :(得分:1)
首先,我们得到data.frames的矩阵,然后我们将rownames添加为一个名为a
的单独列,并将它们全部收集起来。通过取消,我们得到一个大数据框架。使用NA
complete
值
library(tidyverse) # using dplyr, tidyr and purrr
df %>%
mutate(Value = map(Value, as.data.frame),
Value = map(Value, rownames_to_column, 'a'),
Value = map(Value, ~gather(., b, value, -a))) %>%
unnest(Value) %>%
complete(Step, a, b)
手动定义data.frame,然后执行相同的操作:
df %>%
mutate(Value = map(Value,
~data_frame(val = c(.),
a = rep(rownames(.), each = ncol(.)),
b = rep(colnames(.), nrow(.))))) %>%
unnest(Value) %>%
complete(Step, a, b))
两者都给:
# A tibble: 30 × 4 Step a b value <int> <chr> <chr> <dbl> 1 1 4 0.01 NA 2 1 4 0.021 NA 3 1 4 0.044 NA 4 1 4 0.094 0.932 5 1 4 0.2 0.232 6 1 5 0.01 NA 7 1 5 0.021 NA 8 1 5 0.044 NA 9 1 5 0.094 0.875 10 1 5 0.2 0.261 # ... with 20 more rows
答案 1 :(得分:1)
不是真正的INSERT INTO HOTELTABLE(HOTEL_CHAIN,HOTEL_LOCATION,HOTEL_OWNER)
select distinct f1.HOTEL_CHAIN,
ifnull(f2.result, f1.HOTEL_LOCATION) as HOTEL_LOCATION,
ifnull(f3.result, f1.HOTEL_OWNER) as HOTEL_LOCATION,
from BUSINESSTABLE f1
left outer join lateral
(
select 'NULL' result from BUSINESSTABLE f2b
where f1.HOTEL_CHAIN=f2b.HOTEL_CHAIN and f1.HOTEL_LOCATION<>f2b.HOTEL_LOCATION
fetch first rows only
) f2 on 1=1
left outer join lateral
(
select 'NULL' result from BUSINESSTABLE f3b
where f1.HOTEL_CHAIN=f3b.HOTEL_CHAIN and f1.HOTEL_OWNER<>f3b.HOTEL_OWNER
fetch first rows only
) f3 on 1=1
解决方案,但您可以这样做:
dplyr
然后为## Get the maximum length in l$Value and the index where it is observed
m = max(lengths(l$Value))
[1] 10
j = which.max(lengths(l$Value))
[1] 2
,l$Value
的每个元素构建一个数据框,并添加rbind
列:
Step
返回:
l2 = lapply(l$Value,function(x) data.frame(a=rep(row.names(x),length.out=m),
Value=x[1:m],b=rep(colnames(l$Value[[j]]),length.out=m)))
df = do.call(rbind,l2)
df$Step = rep(l$Step,each=m)