【问题标题】:How can I pick an element from a matrix depending on a set of conditions?如何根据一组条件从矩阵中选择一个元素?
【发布时间】:2020-07-09 07:56:27
【问题描述】:

我有一个包含n 行和m 列的数据框。每一行都是一个人,每一列都是关于这个人的信息。

df

id   age   income 
1    18     12
2    24     24
3    36     12
4    18     24
.    .      .
.    .      .
.    .      .

我还有一个矩阵rXc每行显示年龄桶,每列显示收入桶,矩阵的每个元素是每个收入年龄桶的人口百分比。

matrix age\income

     12    24    36  .....
18  0.15  0.12  0.11 ....
24  0.12  0.6   0.2  ...
36  0.02  0.16  0.16 ...
.    ..................
.    ..................

对于数据框中的每个人,我需要在给定个人年龄和收入范围的情况下找到矩阵的正确元素。

所需的输出应如下所示

df2

id   age   income  y
1    18     12    0.15
2    24     24    0.6
3    36     12    0.02
4    18     24    0.12
.    .      .
.    .      .
.    .      .

我尝试在循环中使用一系列 IF(如示例中所示):

for (i in 1:length(df$x)) {
  workingset <- df[i,]
    if(workingset$age==18){
      temp<-marix[1,]
      workingset$y <- ifelse(workingset$income<12, temp[1], ifelse(workingset$income<24,temp[2],ifelse,temp[3])
}else if(workingset$age==24){
      temp<-marix[2,]
      workingset$y <- ifelse(workingset$income<12, temp[1], ifelse(workingset$income<24,temp[2],ifelse,temp[3])
}else if{
...
}
  if(i==1){
    df2 <- workingset
  }else{
    df2<- rbind(df2, workingset)
  }
}

此代码有效,但耗时太长。有没有办法有效地完成这项工作?

【问题讨论】:

  • 请展示您的输入数据示例以及基于该数据的所需输出。
  • 好的,很抱歉造成混乱

标签: r loops dataframe matrix


【解决方案1】:

假设您的数据看起来与显示的完全一样,您可以使用dplyrtidyr

首先将您的矩阵(我将其命名为 my_mat)转换为 data.frame

my_mat %>% 
  as.data.frame() %>%
  mutate(age=rownames(.)) %>%
  pivot_longer(cols=-age, names_to="income", values_to="y") %>%
  mutate(across(where(is.character), as.numeric))  

返回

# A tibble: 9 x 3
    age income     y
  <dbl>  <dbl> <dbl>
1    18     12  0.15
2    18     24  0.12
3    18     36  0.11
4    24     12  0.12
5    24     24  0.6 
6    24     36  0.2 
7    36     12  0.02
8    36     24  0.16
9    36     36  0.16

这可以与您的 data.frame df 一起加入,所以一口气:

my_mat %>% 
  as.data.frame() %>%
  mutate(age=rownames(.)) %>%
  pivot_longer(cols=-age, names_to="income", values_to="y") %>%
  mutate(across(where(is.character), as.numeric)) %>%
  left_join(df, ., by=c("age", "income"))

给你

# A tibble: 4 x 4
     id   age income     y
  <dbl> <dbl>  <dbl> <dbl>
1     1    18     12  0.15
2     2    24     24  0.6 
3     3    36     12  0.02
4     4    18     24  0.12

数据

my_mat <- structure(c(0.15, 0.12, 0.02, 0.12, 0.6, 0.16, 0.11, 0.2, 0.16
), .Dim = c(3L, 3L), .Dimnames = list(c("18", "24", "36"), c("12", 
"24", "36")))

df <- structure(list(id = c(1, 2, 3, 4), age = c(18, 24, 36, 18), income = c(12, 
24, 12, 24)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -4L), spec = structure(list(cols = list(
    id = structure(list(), class = c("collector_double", "collector"
    )), age = structure(list(), class = c("collector_double", 
    "collector")), income = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1), class = "col_spec"))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 2015-07-01
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    相关资源
    最近更新 更多