如何使 R 函数返回多列并将它们附加到数据框中?
Posted
技术标签:
【中文标题】如何使 R 函数返回多列并将它们附加到数据框中?【英文标题】:How to make an R function return multiple columns and append them to a data frame? 【发布时间】:2010-11-26 13:55:03 【问题描述】:从此数据框开始
myDF = structure(list(Value = c(-2, -1, 0, 1, 2)), .Names = "Value", row.names = c(NA, 5L), class = "data.frame")
假设我想在 myDF$Value 的每一行上运行这个函数
getNumberInfo <- function(x)
if(x %% 2 ==0) evenness = "Even" else evenness="Odd"
if(x > 0) positivity = "Positive" else positivity = "NonPositive"
if (positivity == "Positive") logX = log(x) else logX=NA
c(evenness,positivity,logX)
...获取这个数据框
structure(list(Value = c(-2, -1, 0, 1, 2), Evenness = c("Even",
"Odd", "Even", "Odd", "Even"), Positivity = c("NonPositive",
"NonPositive", "NonPositive", "Positive", "Positive"), Log = c(NA,
NA, NA, "0", "0.693147180559945")), row.names = c(NA, 5L), .Names = c("Value",
"Evenness", "Positivity", "Log"), class = "data.frame")
【问题讨论】:
【参考方案1】:您可能希望更改 getNumberInfo
函数以返回列表而不是向量,以便值可以具有不同的类型。事实上,它们都被转换为字符串,这可能不是您想要的 logX
。
getNumberInfo <- function(x)
if(x %% 2 ==0) evenness = "Even" else evenness="Odd"
if(x > 0) positivity = "Positive" else positivity = "NonPositive"
if (positivity == "Positive") logX = log(x) else logX=NA
list(evenness,positivity,logX)
此外,您可以使用名称以获得更好的效果,这样您就不必重复它们:
getNumberInfo <- function(x)
list(evenness = if(x %% 2 ==0) "Even" else "Odd",
positivity = if(x > 0) "Positive" else "NonPositive",
logX = if(x > 0) log(x) else NA)
那么解决方法就变得简单了:
> cbind(myDF, t(sapply(myDF$Value, getNumberInfo)))
Value evenness positivity logX
1 -2 Even NonPositive NA
2 -1 Odd NonPositive NA
3 0 Even NonPositive NA
4 1 Odd Positive 0
5 2 Even Positive 0.6931472
最后,如果您使用ifelse
(可以处理向量)而不是if
,它会变得更加简单,因为您不必调用apply
:
getNumberInfo <- function(x)
list(evenness = ifelse(x %% 2 ==0, "Even", "Odd"),
positivity = ifelse(x > 0, "Positive", "NonPositive"),
logX = ifelse(x > 0, log(x), NA))
> cbind(myDF, getNumberInfo(myDF$Value))
Value evenness positivity logX
1 -2 Even NonPositive NA
2 -1 Odd NonPositive NA
3 0 Even NonPositive NA
4 1 Odd Positive 0.0000000
5 2 Even Positive 0.6931472
最后一个解决方案会发出警告,因为它实际上是在计算每个元素的日志,而不仅仅是带有x>0
的元素。不确定最优雅的处理方式。
【讨论】:
与tapply
相比,t(sapply
做了什么?我不知道用t()
包裹东西有什么作用。我从未见过它记录在案。
t() 转置(例如,将行更改为列,反之亦然)。【参考方案2】:
怎么样:
out <- cbind(myDF, t(apply(myDF, 1, getNumberInfo)))
colnames(out) <- c('Value', 'Evenness', 'Positivity', 'Log')
这给了你:
值均匀度阳性日志 1 -2 偶数 非正数 NA 2 -1 奇数非正数 NA 3 0 偶数 非正数 NA 4 1 奇正 0 5 2 偶正数 0.693147180559945【讨论】:
与tapply
相比,t(apply
做了什么?我不知道用t()
包裹东西有什么作用。我从未见过它记录在案。【参考方案3】:
另一种选择:
> library(plyr)
> df <- mdply(myDF, getNumberInfo)
> names(df) <- c('Value', 'Evenness', 'Positivity', 'Log')
> df
Value Evenness Positivity Log
1 -2 Even NonPositive NA
2 -1 Odd NonPositive NA
3 0 Even NonPositive NA
4 1 Odd Positive 0.0000000
5 2 Even Positive 0.6931472
【讨论】:
以上是关于如何使 R 函数返回多列并将它们附加到数据框中?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ggplot 在 R 中自动绘制图形并将它们保存到文件夹中?