我经常遇到 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/