尝试在拆分功能后添加%列。
写了以下有效的作品:
percs <- function(agg, deporur=0, all=TRUE, full=FALSE){
work <- data.frame(NoNA$IMD_NATIONAL_QUINTILE, NoNA$UR,agg)
work <- as.data.frame(table(work))
work <-split(work, work[,deporur])
work
}
使用我的数据,返回:
$`1`
NoNA.IMD_NATIONAL_QUINTILE NoNA.UR agg Freq
1 1 0 1 0
6 1 Rural 1 0
11 1 Urban 1 43
16 1 0 2 0
21 1 Rural 2 0
26 1 Urban 2 37
$`2`
NoNA.IMD_NATIONAL_QUINTILE NoNA.UR agg Freq
2 2 0 1 0
7 2 Rural 1 3
12 2 Urban 1 30
17 2 0 2 0
22 2 Rural 2 1
27 2 Urban 2 27
$`3`
NoNA.IMD_NATIONAL_QUINTILE NoNA.UR agg Freq
3 3 0 1 0
8 3 Rural 1 7
13 3 Urban 1 25
18 3 0 2 0
23 3 Rural 2 3
28 3 Urban 2 13
$`4`
NoNA.IMD_NATIONAL_QUINTILE NoNA.UR agg Freq
4 4 0 1 0
9 4 Rural 1 9
14 4 Urban 1 30
19 4 0 2 0
24 4 Rural 2 0
29 4 Urban 2 18
$`5`
NoNA.IMD_NATIONAL_QUINTILE NoNA.UR agg Freq
5 5 0 1 0
10 5 Rural 1 13
15 5 Urban 1 40
20 5 0 2 0
25 5 Rural 2 11
30 5 Urban 2 27
我想在每个末尾添加一个额外的列,以显示每个列的百分比。
我可以在控制台中使用它,如下所示:
test<-percs(NoNA$Q1, 1)
test$"1"$newcol <- test$"1"[,4]/sum(test$"1"[,4])
test$"1"
NoNA.IMD_NATIONAL_QUINTILE NoNA.UR agg Freq newcol
1 1 0 1 0 0.0000
6 1 Rural 1 0 0.0000
11 1 Urban 1 43 0.5375
16 1 0 2 0 0.0000
21 1 Rural 2 0 0.0000
26 1 Urban 2 37 0.4625
但是,我无法弄清楚如何使其循环工作,遍历工作数据框中存储的每个数据框并添加其他列。如果我使用$运算符访问对象,那么它允许我使用数据帧,但是使用[]通常在for循环中运行的[]运算符,它返回列表并且不会让我添加一列。
有关我在哪里出错的想法吗?
答案 0 :(得分:4)
这是测试数据的简单版本
df <- expand.grid(type=1:10, qty=1:5)
split(df, df$type)
$`1`
type qty
1 1 1
11 1 2
21 1 3
31 1 4
41 1 5
$`2`
type qty
2 2 1
12 2 2
22 2 3
32 2 4
42 2 5
...
然后计算百分比,你可以使用lapply
> lapply(split(df, df$type), function(d) { d$asdf <- cumsum(d$qty)/sum(d$qty); d })
$`1`
type qty asdf
1 1 1 0.06666667
11 1 2 0.20000000
21 1 3 0.40000000
31 1 4 0.66666667
41 1 5 1.00000000
$`2`
type qty asdf
2 2 1 0.06666667
12 2 2 0.20000000
22 2 3 0.40000000
32 2 4 0.66666667
42 2 5 1.00000000
...
答案 1 :(得分:4)
仅仅因为我的评论变得越来越长:
只需使用
perc <- lapply(work, function(x) x[, 4] / sum(x[, 4] )
然后附加到您的数据。我无法测试我的代码,因为很难读取您的数据(至少对我而言),如果您提供dput
数据可能会更好。即使dplyr
方法会更好,例如:
df %>% group_by(NoNA.IMD_NATIONAL_QUINTILE) %>% mutate(perc = Freq / sum(Freq))
答案 2 :(得分:3)
如果没有您的数据样本,我也无法测试我的答案,但我认为使用ddply
代替split
(或split
ddply
之后如果你想要列表,那就是要走的路。
我相信你应该能够做到这样的事情:
library(plyr)
test <- ddply(work, .(NoNA.IMD_NATIONAL_QUINTILE), summarize, newcol = Freq/sum(Freq))
答案 3 :(得分:1)
这是您的数据集
> dt <- expand.grid(type=1:2, qty=1:5)
> dt = split(dt, dt$type)
>
> dt
$`1`
type qty
1 1 1
3 1 2
5 1 3
7 1 4
9 1 5
$`2`
type qty
2 2 1
4 2 2
6 2 3
8 2 4
10 2 5
这是循环(如果你真的想要一个循环)使用[[]]而不是[]:
> for (i in 1:length(dt)){
+ dt[[i]]$prc = dt[[i]]$qty/sum(dt[[i]]$qty)
+ }
>
> dt
$`1`
type qty prc
1 1 1 0.06666667
3 1 2 0.13333333
5 1 3 0.20000000
7 1 4 0.26666667
9 1 5 0.33333333
$`2`
type qty prc
2 2 1 0.06666667
4 2 2 0.13333333
6 2 3 0.20000000
8 2 4 0.26666667
10 2 5 0.33333333
这是一个将列表元素组合到一个数据集的dplyr版本:
> dt <- expand.grid(type=1:2, qty=1:5)
> dt = split(dt, dt$type)
>
> do.call(rbind, dt) %>% group_by(type) %>% mutate(prc = qty/sum(qty)) %>% ungroup
Source: local data frame [10 x 3]
type qty prc
1 1 1 0.06666667
2 1 2 0.13333333
3 1 3 0.20000000
4 1 4 0.26666667
5 1 5 0.33333333
6 2 1 0.06666667
7 2 2 0.13333333
8 2 3 0.20000000
9 2 4 0.26666667
10 2 5 0.33333333
答案 4 :(得分:1)
看起来我最终到了那里,非常感谢你的帮助。
使用[[]]代替[]
时出现问题percs <- function(agg, deporur=0, all=TRUE, full=FALSE){
work <- data.frame(NoNA$IMD_NATIONAL_QUINTILE, NoNA$UR,agg)
work <- as.data.frame(table(work))
work <-split(work, work[,deporur])
for(i in 1:length(work)){
x<-as.data.frame(work[i])
work[[i]]$NewCol <-x[,4]/sum(x[,4])
}
work
}