【问题标题】:R loop to copy content from two columns, according a third column, and output into a fourth columnR循环根据第三列从两列复制内容,并输出到第四列
【发布时间】:2020-12-01 00:00:29
【问题描述】:

我知道类似问题的解决方案,并已通读我找到的所有内容(因此提供了下面的代码),但遗憾的是无法使它们正常工作。另外,我对循环很不熟悉......

我正在尝试做的事情:我有一个数据集 data 并尝试从 length_L1 列或 length_L2 列中输入 Cov_length 列中的值,具体取决于第三列中的值:Language: A) 如果Language 在特定行L1 中声明,则我将列length_L1 中的相应行值输入Cov_length。 B)如果Language中的值为L2,则将length_L2对应的行值输入Cov_length

这是一些示例数据:

data111 <- data.frame(Language = c("L1","L1", "L2", "L1", "L2", "L2", "L2", "L1"),
                      Length_L1 = c(4, 7, 3, 12, 10, 5, 5, 7),
                      Length_L2 = c(5, 2, 9, 7, 3, 3, 4, 10),
                      Cov_length = c(0, 0, 0, 0, 0, 0, 0, 0))
> data111
  Language Length_L1 Length_L2 Cov_length
1       L1         4         5          0
2       L1         7         2          0
3       L2         3         9          0
4       L1        12         7          0
5       L2        10         3          0
6       L2         5         3          0
7       L2         5         4          0
8       L1         7        10          0

这是我尝试过的两种解决方案。第一个运行没有错误,但不执行任何操作(Cov_length 中的值保持为零)。

for (i in 1:length(data$Language)) {
  if (i == "L1") {data$Cov_length [i] <- data$length_L1 [i] }
  else if (i == "L2") {data$Cov_length [i] <- data$length_L2 [i] }
  else {}
}

第二个解决方案只是从列length_L1 中获取所有值,而不是实际选择两列之间的值。

require(base)  
data %>% 
  mutate (Cov_length = ifelse(Language == "L1", paste(length_L1), paste(length_L2))) 

在我的数据中有很多情况我必须执行上述操作,它是一个 8000 次观察的片段,L1/L2 值的随机顺序(我无法有效地手动完成) .因此,任何建议都会有所帮助。谢谢!

【问题讨论】:

    标签: r for-loop if-statement


    【解决方案1】:

    我们不需要paste。列名应不加引号以返回值

    library(dplyr)
    data111 <- data111 %>% 
           mutate(Cov_length = ifelse(Language == 'L1', Length_L1, Length_L2))
    

    -输出

    data111
    #  Language Length_L1 Length_L2 Cov_length
    #1       L1         4         5          4
    #2       L1         7         2          7
    #3       L2         3         9          9
    #4       L1        12         7         12
    #5       L2        10         3          3
    #6       L2         5         3          3
    #7       L2         5         4          4
    #8       L1         7        10          7
    

    如果有两个以上的组和多个'Length'列,可以reshape为'long'格式并得到正确的值

    library(tidyr)
    library(stringr)
    data111 %>% 
        mutate(rn = row_number()) %>%
        select(-Cov_length) %>% 
        pivot_longer(cols = starts_with('Length')) %>% 
        group_by(rn) %>%
        summarise(Cov_length = value[str_detect(name, first(Language))], 
               .groups = 'drop') %>% 
        pull(Cov_length) %>% 
        mutate(data111, Cov_length = .)
    

    或使用base R

    nm1 <- grep('^Length', names(data111), value = TRUE)
    data111$Cov_length <-  data111[nm1][cbind(seq_len(nrow(data111)), 
              match(data111$Language, sub("Length_", "", nm1)))]
    

    【讨论】:

    • 我只是做了同样的事情,我的输出更加令人困惑,对我来说没有意义:` > data111 %>% + mutate (Cov_length = ifelse(Language == "L1", length_L1 , length_EN)) 语言 Length_L1 Length_L2 Cov_length 1 L1 4 5 10 2 L1 7 2 5 3 L2 3 9 5 4 L1 12 7 6 5 L2 10 3 5 6 L2 5 3 4 7 L2 5 4 4 8 L1 7 10 5 `
    • @Orestes_Fox 我更新了我得到的输出。
    • 谢谢!它是适合我的基本 R 解决方案(由于某种原因,我在第一个解决方案中得到完全不同且混乱的数字)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多