R:避免在使用应用函数时将单行数据帧转换为向量

标签 r dataframe apply purrr

我经常遇到 R 将我的一列数据帧转换为字符向量的问题,我使用 drop=FALSE 选项解决了这个问题。

但是,在某些情况下,我不知道如何在 R 中解决此类行为,这就是其中之一。

我有一个如下所示的数据框:

mydf <- data.frame(ID=LETTERS[1:3], value1=paste(LETTERS[1:3], 1:3), value2=paste(rev(LETTERS)[1:3], 1:3))

看起来像:

> mydf
  ID value1 value2
1  A    A 1    Z 1
2  B    B 2    Y 2
3  C    C 3    X 3

我在这里做的任务是用 _ 替换除第一列之外的每一列中的空格,我想为此使用 apply 系列函数,sapply 在这种情况下。

我做了以下事情:

new_df <- as.data.frame(sapply(mydf[,-1,drop=F], function(x) gsub("\\s+","_",x)))
new_df <- cbind(mydf[,1,drop=F], new_df)

生成的数据框看起来正是我想要的:

> new_df
  ID value1 value2
1  A    A_1    Z_1
2  B    B_2    Y_2
3  C    C_3    X_3

我的问题始于一些罕见的情况,在这些情况下,我的输入只能包含一行数据。出于某种我不明白的原因,R 在这些情况下有完全不同的行为,但是没有 drop=FALSE 选项可以救我...

我现在的输入数据框是:

mydf <- data.frame(ID=LETTERS[1], value1=paste(LETTERS[1], 1), value2=paste(rev(LETTERS)[1], 1))

看起来像:

> mydf
  ID value1 value2
1  A    A 1    Z 1

但是,当我应用相同的代码时,生成的数据框看起来像这样丑陋:

> new_df
       ID sapply(mydf[, -1, drop = F], function(x) gsub("\\\\s+", "_", x))
value1  A                                                              A_1
value2  A                                                              Z_1

如何解决这个问题,以便同一行代码为任意行数的输入数据帧提供相同类型的结果?

一个更深层次的问题是,R 到底为什么要这样做?当我有一些带有一行/一列的新奇怪输入时,我会继续回到我的代码,因为它们破坏了一切......谢谢!

最佳答案

您可以使用lapply 代替sapply 来解决您的问题,然后使用do.call 组合结果如下

new_df <- as.data.frame(lapply(mydf[,-1,drop=F], function(x) gsub("\\s+","_",x)))
new_df <- do.call(cbind, new_df)
new_df
#     value1 value2
#[1,] "A_1"  "Z_1" 

new_df <- cbind(mydf[,1,drop=F], new_df)
#new_df
#  ID value1 value2
#1  A    A_1    Z_1

至于你关于sapply不可预知行为的问题,是因为sapply中的s代表了简化,但不能保证简化后的结果是数据框。它可以是数据框、矩阵或向量。

根据sapply的文档:

sapply is a user-friendly version and wrapper of lapply by default returning a vector, matrix or, if simplify = "array", an array if appropriate, by applying simplify2array().

关于简化参数:

logical or character string; should the result be simplified to a vector, matrix or higher dimensional array if possible? For sapply it must be named and not abbreviated. The default value, TRUE, returns a vector or matrix if appropriate, whereas if simplify = "array" the result may be an array of “rank” (=length(dim(.))) one higher than the result of FUN(X[[i]]).

Details 部分解释了其与您所经历的相似的行为(重点来 self ):

Simplification in sapply is only attempted if X has length greater than zero and if the return values from all elements of X are all of the same (positive) length. If the common length is one the result is a vector, and if greater than one is a matrix with a column corresponding to each element of X.

Hadley Wickham 还建议不要使用 sapply:

I recommend that you avoid sapply() because it tries to simplify the result, so it can return a list, a vector, or a matrix. This makes it difficult to program with, and it should be avoided in non-interactive settings

他还建议不要对数据框使用 apply。参见 Advanced R进一步解释。

关于R:避免在使用应用函数时将单行数据帧转换为向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71509818/

相关文章:

python - 合并没有匹配列的数据框

r - 跨多个列计算出现次数并按年份分组

R ztable 包中的百分比符号在编织为 pdf 时抛出\hline 错误

r - 如何从 R 中的多个 id 中获取独占和总计数

javascript - 申请(): what do square brackets mean with a function in-between?

javascript - 当我们可以直接调用方法时,为什么我们需要在javascript中调用或应用方法?

根据矩阵中的值重复向量元素

R-forge vs Rforge?

r - 在 R 包描述文件中指定仅 Windows 兼容性

python - 在中间步骤中引用链式 Pandas DF