考虑这个例子:
df <- data.frame(id=1:10,var1=LETTERS[1:10],var2=LETTERS[6:15])
fun.split <- function(x) tolower(as.character(x))
df$new.letters <- apply(df[ ,2:3],2,fun.split)
df$new.letters.var1
#NULL
colnames(df)
# [1] "id" "var1" "var2" "new.letters"
df$new.letters
# var1 var2
# [1,] "a" "f"
# [2,] "b" "g"
# [3,] "c" "h"
# [4,] "d" "i"
# [5,] "e" "j"
# [6,] "f" "k"
# [7,] "g" "l"
# [8,] "h" "m"
# [9,] "i" "n"
# [10,] "j" "o"
Run Code Online (Sandbox Code Playgroud)
会有人这么善良并解释这里发生了什么吗?数据框中的新数据框架?
我期待这个:
colnames(df)
# id var1 var2 new.letters.var1 new.letters.var2
Run Code Online (Sandbox Code Playgroud)
akr*_*run 12
原因是您为2列matrix输出分配了一个新列apply.因此,结果将是一个matrix列.您可以将其转换回普通的data.frame
do.call(data.frame, df)
Run Code Online (Sandbox Code Playgroud)
一个更简单的方法是分配2列,lapply而不是apply因为可能存在列具有不同类的情况. apply返回一个matrix并且使用混合类,列将是'character'类.但是,lapply获取输出list并保留class
df[paste0('new.letters', names(df)[2:3])] <- lapply(df[2:3], fun.split)
Run Code Online (Sandbox Code Playgroud)
@akrun 解决了我 90% 的问题。但是我将 data.frames 埋在 data.frames 中,埋在 data.frames 中等等,但不知道发生这种情况的深度。
在这种情况下,我认为分享我的递归解决方案可能有助于其他人像我一样搜索此线程:
unnest_dataframes <- function(x) {
y <- do.call(data.frame, x)
if("data.frame" %in% sapply(y, class)) unnest_dataframes(y)
y
}
new_data <- unnest_dataframes(df)
Run Code Online (Sandbox Code Playgroud)
尽管这本身有时会出现问题,但将“data.frame”类的所有列与原始数据集分开然后 cbind() 将其重新组合在一起可能会有所帮助,如下所示:
# Find all columns that are data.frame
# Assuming your data frame is stored in variable 'y'
data.frame.cols <- unname(sapply(y, function(x) class(x) == "data.frame"))
z <- y[, !data.frame.cols]
# All columns of class "data.frame"
dfs <- y[, data.frame.cols]
# Recursively unnest each of these columns
unnest_dataframes <- function(x) {
y <- do.call(data.frame, x)
if("data.frame" %in% sapply(y, class)) {
unnest_dataframes(y)
} else {
cat('Nested data.frames successfully unpacked\n')
}
y
}
df2 <- unnest_dataframes(dfs)
# Combine with original data
all_columns <- cbind(z, df2)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6951 次 |
| 最近记录: |