根据 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 可以采用值 meanpercentage 为例),并且仅在输出中显示为百分比。 (而且我认为您需要乘以 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%

但是,请注意,一列只能包含一种类型的数据,因此此处所有值都将变为字符,因为我们添加了 % 符号。