根据 R 中的行名称操作列值
manipulate the column value based on the row names in R
我正在尝试根据行名称操作列值,我们将不胜感激。
data(mtcars)
mtcars$gear1 <- factor(mtcars$gear, levels = c(3,4,5))
my.mean <- function(x) if(is.numeric(x)) mean(x) else prop.table(table(x))
B <- setNames(as.data.frame(unlist(lapply(mtcars, FUN = my.mean))), "mean")
class(B)
row.names(B)
put.per <- c("gear1.3", "gear1.4", "gear1.5")
sapply(row.names(B),function(x){
if(x %in% put.per) paste(B$mean, "%", sep = "")
})
预期答案
mean
mpg 20.090625
cyl 6.187500
disp 230.721875
hp 146.687500
drat 3.596563
wt 3.217250
qsec 17.848750
vs 0.437500
am 0.406250
gear 3.687500
carb 2.812500
gear1.3 0.468750%
gear1.4 0.375000%
gear1.5 0.156250%
非常感谢
使用行名通常不是一个好主意,因为它会从数据框的单元格中删除信息。最好将原始变量名称存储在操作数据集的列中。
在 dplyr
v1.0.0.0 中,执行此操作的代码很紧凑。
d <- mtcars %>%
summarise(across(everything(), mean)) %>%
pivot_longer(names_to="variable", values_to="mean", cols=everything())
d
# A tibble: 11 x 2
variable mean
* <chr> <dbl>
1 mpg 20.1
2 cyl 6.19
3 disp 231.
4 hp 147.
5 drat 3.60
6 wt 3.22
7 qsec 17.8
8 vs 0.438
9 am 0.406
10 gear 3.69
11 carb 2.81
如果您必须在小标题中使用行名而不是列名:
row.names(d) <- d$variable
d <- d %>% select(-variable)
我刚看到你的 gear.x
行。你想在那里做什么?
更新
完整解决方案:
mtcars %>%
summarise(across(everything(), mean)) %>%
pivot_longer(names_to="variable", values_to="mean", cols=everything()) %>%
mutate(mean=as.character(mean)) %>%
bind_rows(
mtcars %>%
group_by(gear) %>%
summarise(mean=sprintf("%8.6f%%", n()/nrow(.))) %>%
mutate(variable=paste0("gear.", gear)) %>%
select(-gear)
)
# A tibble: 14 x 2
variable mean
<chr> <chr>
1 mpg 20.090625
2 cyl 6.1875
3 disp 230.721875
4 hp 146.6875
5 drat 3.5965625
6 wt 3.21725
7 qsec 17.84875
8 vs 0.4375
9 am 0.40625
10 gear 3.6875
11 carb 2.8125
12 gear.3 0.468750%
13 gear.4 0.375000%
14 gear.5 0.156250%
就个人而言,我不会将齿轮的百分比格式化为数据中的字符 frame/tibble。我会将它们存储为双精度值(并添加一个指示器列来定义 mean
中显示的数据类型,并将 mean
重命名为更具代表性的名称,例如 statistic
- 在这种情况下,指示器column 可以采用值 mean
和 percentage
为例),并且仅在输出中显示为百分比。 (而且我认为您需要乘以 100 才能得到百分比。您目前有标记为百分比的分数。)
您在这里不需要 sapply
或任何其他类型的循环。您可以找到存在 put.per
值的行索引,并使用 paste0
.
更改它们
inds <- rownames(B) %in% put.per
B$mean[inds] <- paste0(B$mean[inds], "%")
B
# mean
#mpg 20.090625
#cyl 6.1875
#disp 230.721875
#hp 146.6875
#drat 3.5965625
#wt 3.21725
#qsec 17.84875
#vs 0.4375
#am 0.40625
#gear 3.6875
#carb 2.8125
#gear1.3 0.46875%
#gear1.4 0.375%
#gear1.5 0.15625%
但是,请注意,一列只能包含一种类型的数据,因此此处所有值都将变为字符,因为我们添加了 %
符号。
我正在尝试根据行名称操作列值,我们将不胜感激。
data(mtcars)
mtcars$gear1 <- factor(mtcars$gear, levels = c(3,4,5))
my.mean <- function(x) if(is.numeric(x)) mean(x) else prop.table(table(x))
B <- setNames(as.data.frame(unlist(lapply(mtcars, FUN = my.mean))), "mean")
class(B)
row.names(B)
put.per <- c("gear1.3", "gear1.4", "gear1.5")
sapply(row.names(B),function(x){
if(x %in% put.per) paste(B$mean, "%", sep = "")
})
预期答案
mean
mpg 20.090625
cyl 6.187500
disp 230.721875
hp 146.687500
drat 3.596563
wt 3.217250
qsec 17.848750
vs 0.437500
am 0.406250
gear 3.687500
carb 2.812500
gear1.3 0.468750%
gear1.4 0.375000%
gear1.5 0.156250%
非常感谢
使用行名通常不是一个好主意,因为它会从数据框的单元格中删除信息。最好将原始变量名称存储在操作数据集的列中。
在 dplyr
v1.0.0.0 中,执行此操作的代码很紧凑。
d <- mtcars %>%
summarise(across(everything(), mean)) %>%
pivot_longer(names_to="variable", values_to="mean", cols=everything())
d
# A tibble: 11 x 2
variable mean
* <chr> <dbl>
1 mpg 20.1
2 cyl 6.19
3 disp 231.
4 hp 147.
5 drat 3.60
6 wt 3.22
7 qsec 17.8
8 vs 0.438
9 am 0.406
10 gear 3.69
11 carb 2.81
如果您必须在小标题中使用行名而不是列名:
row.names(d) <- d$variable
d <- d %>% select(-variable)
我刚看到你的 gear.x
行。你想在那里做什么?
更新
完整解决方案:
mtcars %>%
summarise(across(everything(), mean)) %>%
pivot_longer(names_to="variable", values_to="mean", cols=everything()) %>%
mutate(mean=as.character(mean)) %>%
bind_rows(
mtcars %>%
group_by(gear) %>%
summarise(mean=sprintf("%8.6f%%", n()/nrow(.))) %>%
mutate(variable=paste0("gear.", gear)) %>%
select(-gear)
)
# A tibble: 14 x 2
variable mean
<chr> <chr>
1 mpg 20.090625
2 cyl 6.1875
3 disp 230.721875
4 hp 146.6875
5 drat 3.5965625
6 wt 3.21725
7 qsec 17.84875
8 vs 0.4375
9 am 0.40625
10 gear 3.6875
11 carb 2.8125
12 gear.3 0.468750%
13 gear.4 0.375000%
14 gear.5 0.156250%
就个人而言,我不会将齿轮的百分比格式化为数据中的字符 frame/tibble。我会将它们存储为双精度值(并添加一个指示器列来定义 mean
中显示的数据类型,并将 mean
重命名为更具代表性的名称,例如 statistic
- 在这种情况下,指示器column 可以采用值 mean
和 percentage
为例),并且仅在输出中显示为百分比。 (而且我认为您需要乘以 100 才能得到百分比。您目前有标记为百分比的分数。)
您在这里不需要 sapply
或任何其他类型的循环。您可以找到存在 put.per
值的行索引,并使用 paste0
.
inds <- rownames(B) %in% put.per
B$mean[inds] <- paste0(B$mean[inds], "%")
B
# mean
#mpg 20.090625
#cyl 6.1875
#disp 230.721875
#hp 146.6875
#drat 3.5965625
#wt 3.21725
#qsec 17.84875
#vs 0.4375
#am 0.40625
#gear 3.6875
#carb 2.8125
#gear1.3 0.46875%
#gear1.4 0.375%
#gear1.5 0.15625%
但是,请注意,一列只能包含一种类型的数据,因此此处所有值都将变为字符,因为我们添加了 %
符号。