每当我想在R中做一些"map"py时,我通常会尝试使用一个函数 apply家族中.
但是,我从来没有完全理解它们之间的区别 - 如何{ sapply,lapply等}将函数应用于输入/分组输入,输出将是什么样的,甚至输入可以是什么 - 所以我经常只要仔细检查它们,直到我得到我想要的东西.
有人可以解释如何使用哪一个?
我当前(可能不正确/不完整)的理解是......
sapply(vec, f):输入是一个向量.output是一个向量/矩阵,其中element i是f(vec[i])一个矩阵,如果f有一个多元素输出
lapply(vec, f):相同sapply,但输出是一个列表?
apply(matrix, 1/2, f):输入是一个矩阵.output是一个向量,其中element i是f(矩阵的row/col i)tapply(vector, grouping, f):output是一个矩阵/数组,其中矩阵/数组中的元素是向量f分组g的值,和g被推送到行/列名称by(dataframe, grouping, f):让我们g成为一个分组.适用f于组/数据框的每一列.漂亮打印分组和f每列的值.aggregate(matrix, grouping, f):类似于by,但不是将输出打印得很漂亮,而是将所有内容都粘贴到数据帧中.侧问题:我还没有学会plyr或重塑-将plyr或reshape更换所有这些完全?
是否可以在单个tapply或aggregate语句中包含两个函数?
下面我使用两个tapply语句和两个聚合语句:一个用于均值,一个用于SD.
我更愿意结合这些陈述.
my.Data = read.table(text = "
animal age sex weight
1 adult female 100
2 young male 75
3 adult male 90
4 adult female 95
5 young female 80
", sep = "", header = TRUE)
with(my.Data, tapply(weight, list(age, sex), function(x) {mean(x)}))
with(my.Data, tapply(weight, list(age, sex), function(x) {sd(x) }))
with(my.Data, aggregate(weight ~ age + sex, FUN = mean)
with(my.Data, aggregate(weight ~ age + sex, FUN = sd)
# this does not work:
with(my.Data, tapply(weight, list(age, sex), function(x) …Run Code Online (Sandbox Code Playgroud) 我想按组分列各个列,我的第一个想法是使用tapply.但是,我无法tapply上班.可以tapply用来汇总多列吗?如果没有,为什么不呢?
我已经广泛搜索了互联网,发现很多类似的问题早在2008年就已发布.但是,这些问题都没有直接得到解答.相反,响应总是建议使用不同的功能.
下面是一个示例数据集,我希望按州分配苹果,按州和国家分析李子.在此之下,我已经编译了许多替代方案tapply.
在底部,我展示了对tapply源代码的简单修改,允许
tapply执行所需的操作.
不过,也许我忽略了一种简单的方法来执行所需的操作tapply.我不是在寻找替代功能,但欢迎其他替代方案.
鉴于我对tapply源代码的修改很简单,我想知道为什么它或类似的东西还没有实现.
谢谢你的任何建议.如果我的问题是重复的,我很乐意将我的问题作为对其他问题的回答.
以下是示例数据集:
df.1 <- read.table(text = '
state county apples cherries plums
AA 1 1 2 3
AA 2 10 20 30
AA 3 100 200 300
BB 7 -1 -2 -3
BB 8 -10 -20 -30
BB 9 -100 -200 -300
', header = TRUE, stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)
这不起作用:
tapply(df.1, df.1$state, function(x) {colSums(x[,3:5])})
Run Code Online (Sandbox Code Playgroud)
帮助页面说:
tapply(X, INDEX, FUN …Run Code Online (Sandbox Code Playgroud) 我想从一个数据帧计算mean和sd,参数为一列,组标识为一列.使用时如何计算tapply?我可以使用sd(v1, group, na.rm=TRUE),但na.rm=TRUE在使用时不适合语句tapply.
omit.na别无选择.我有一大堆参数,在排除所有缺少值的行时,必须逐步完成它们而不会丢失一半的数据帧.
data("weightgain", package = "HSAUR")
tapply(weightgain$weightgain, list(weightgain$source, weightgain$type), mean)
Run Code Online (Sandbox Code Playgroud)
by声明也是如此.
x<-c(1,2,3,4,5,6,7,8,9,NA)
y<-c(2,3,NA,3,4,NA,2,3,NA,2)
group<-rep((factor(LETTERS[1:2])),5)
df<-data.frame(x,y,group)
df
by(df$x,df$group,summary)
by(df$x,df$group,mean)
sd(df$x) #result: NA
sd(df$x, na.rm=TRUE) #result: 2.738613
Run Code Online (Sandbox Code Playgroud)
有任何想法如何完成这项工作?
我有以下数据:
a <- c(1,1,1,1,2,2,2,2)
b <- c(2,4,6,8,2,3,4,1)
c <- factor(c("A","B","A","B","A","B","A","B"))
df <- data.frame(
sp=a,
length=b,
method=c)
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法通过方法计算每个物种的样本数量:
n <- with(df,tapply(sp,method,function(x) count(x)))
Run Code Online (Sandbox Code Playgroud)
我如何通过每个物种的方法获得平均长度?
我有一个矩阵data.mat,看起来像:
A B C D E
45 43 45 65 23
12 45 56 NA NA
13 4 34 12 NA
Run Code Online (Sandbox Code Playgroud)
我试图把它变成一个列表列表,其中每一行是一个更大的列表中的一个列表.我做以下事情:
list <- tapply(data.mat,rep(1:nrow(data.mat),ncol(data.mat)),function(i)i)
Run Code Online (Sandbox Code Playgroud)
这给了我一个包含NA的列表列表,例如:
$`1`
[1] 45 43 45 65 23
$`2`
[1] 12 45 56 NA NA
$`3`
[1] 13 4 34 12 NA
Run Code Online (Sandbox Code Playgroud)
但我想要的是:
$`1`
[1] 45 43 45 65 23
$`2`
[1] 12 45 56
$`3`
[1] 13 4 34 12
Run Code Online (Sandbox Code Playgroud)
是否有一种很好的方法可以在tapply呼叫期间或之后删除NA?
似乎普遍认为"lapply"中的l代表列表,"sapply"中的s代表简化,而"rapply"中的r代表递归.但我在"tapply"中找不到任何东西.我现在很好奇.
我通过玩弄来学习R,我开始认为我在滥用tapply功能.是否有更好的方法可以执行以下某些操作?当然,他们工作,但随着他们变得越来越复杂,我想知道我是否会失去更好的选择.我在寻找一些批评,在这里:
tapply(var1, list(fac1, fac2), mean, na.rm=T)
tapply(var1, fac1, sum, na.rm=T) / tapply(var2, fac1, sum, na.rm=T)
cumsum(tapply(var1, fac1, sum, na.rm=T)) / sum(var1)
Run Code Online (Sandbox Code Playgroud)
更新:这是一些示例数据......
var1 var2 fac1 fac2
1 NA 275.54 10 (266,326]
2 NA 565.89 10 (552,818]
3 NA 815.41 6 (552,818]
4 NA 281.77 6 (266,326]
5 NA 640.24 NA (552,818]
6 NA 78.42 NA [78.4,266]
7 NA 1027.06 NA (818,1.55e+03]
8 NA 355.20 NA (326,552]
9 NA 464.52 NA (326,552]
10 NA 1397.11 10 (818,1.55e+03]
11 NA 229.82 NA …Run Code Online (Sandbox Code Playgroud) 我的问题是:我有一个带有一些因子变量的数据框.我现在想为这个数据帧分配一个新的向量,它为这些因子变量的每个子集创建一个索引.
data <-data.frame(fac1=factor(rep(1:2,5)), fac2=sample(letters[1:3],10,rep=T))
Run Code Online (Sandbox Code Playgroud)
给我一些类似的东西:
fac1 fac2
1 1 a
2 2 c
3 1 b
4 2 a
5 1 c
6 2 b
7 1 a
8 2 a
9 1 b
10 2 c
Run Code Online (Sandbox Code Playgroud)
我想要的是一个组合计数器,它计算每个因子组合的出现次数.像这样
fac1 fac2 counter
1 1 a 1
2 2 c 1
3 1 b 1
4 2 a 1
5 1 c 1
6 2 b 1
7 1 a 2
8 2 a 2
9 1 b 2
10 1 a …Run Code Online (Sandbox Code Playgroud) 如何将tapply命令与'not in'逻辑结合起来?
目标:获得每个物种的中位萼片长度.
tapply(iris$Sepal.Length, iris$Species, median)
Run Code Online (Sandbox Code Playgroud)
约束:删除花瓣宽度为1.3和1.5的条目.
!iris$Petal.Width %in% c('1.3', '1.5')
Run Code Online (Sandbox Code Playgroud)
尝试:
tapply(iris$Sepal.Length, iris$Species, median[!iris$Petal.Width %in% c('1.3', '1.5')])
Run Code Online (Sandbox Code Playgroud)
结果:错误消息'类型'对象'的对象'不是子集表'.
---
我在这里使用iris数据集的尝试是我自己的数据集的替代演示.我使用自己的数据集尝试了相同的方法并收到了相同的错误消息.我想我的语法有问题.它是什么?