根据列标题名称的匹配开头组合R中的列

时间:2018-02-09 20:53:48

标签: r for-loop

我的数据框看起来有点像以下内容。 A1U_sweet实际上是实际数据帧中的第19列,而C1U_sweet是实际数据帧中的第39列。有20列以A ##开头,20列以C ##开头。

A1U_sweet  A2F_dip  A3U_bbq  C1U_sweet  C2F_dip  C3U_bbq
1          2        1        NA         NA       NA
NA         NA       NA       4          1        2
2          4        7        NA         NA       NA

我想制作组合A值和C值的其他列。生成的数据框将包含类似于B1U_sweet和B2F_dip的列。

A1U_sweet  A2F_dip  A3U_bbq  C1U_sweet  C2F_dip  C3U_bbq  B1U_sweet  B2F_dip
1          2        1        NA         NA       NA       1          2
NA         NA       NA       4          1        2        4          1
2          4        7        NA         NA       NA       2          4

有人提议我尝试以下代码。前两行有效,但在实现其余部分之后,我收到一条错误消息。

types <- grep('^A([0-9]|[12][0-9])[A-Z]_[a-z]+', names(df)) ## Get all "A" 
patterns
types <- substr(types, 2, Inf) ## Remove the "A"
for (tp in types) {
  aa <- df[[paste0('A', tp)]] ## "A" column
  cc <- df[[paste0('C', tp)]] ## "C" column
  df[[paste0('B', tp)]] <- ifelse(is.na(aa), aa, cc)
}

这是错误消息:

Error in `[[<-.data.frame`(`*tmp*`, paste0("B", tp), value = logical(0)) : 
  replacement has 0 rows, data has 94
In addition: Warning message:
In is.na(aa) : is.na() applied to non-(list or vector) of type 'NULL'

数据确实有94列,但我不明白为什么可能会触发此错误。我很感激任何帮助使这个代码正常运行!

编辑:这是我到目前为止所做的。我必须进入并手动更改我想要组合的每组列的列名。一定有更好的方法!

df$B1U_sweetnsour<-A1U_sweetnsour
df$B1U_sweetnsour[is.na(df$B1U_sweetnsour)]<- C1U_sweetnsour[is.na(A1U_sweetnsour)]

3 个答案:

答案 0 :(得分:1)

考虑mapply以元素方式比较 A 列和 C 列,并一次性分配所有 B 列。并使用与sub不同的gsubsub仅替换第一次出现,以防列标题中的其他地方出现A.

new_B_cols <- sub("A", "B", names(df)[grep("^A", names(df))])

replace_na <- function(aa, cc) {
     aa[is.na(aa)] <- cc[is.na(aa)]
     return(aa) 
}

df[new_B_cols] <- mapply(replace_na, df[grep("^A", names(df))], df[grep("^C", names(df))])

df[order(names(df))]
#   A1U_sweet A2F_dip A3U_bbq B1U_sweet B2F_dip B3U_bbq C1U_sweet C2F_dip C3U_bbq
# 1         1       2       1         1       2       1        NA      NA      NA
# 2        NA      NA      NA         4       1       2         4       1       2
# 3         2       4       7         2       4       7        NA      NA      NA

答案 1 :(得分:0)

尝试使用head(types)来查看您的类型对象是否具有您希望的信息。如果没有,向grep命令添加value = TRUE可能是您正在寻找的解决方案。

types <- grep('^A([0-9]|[12][0-9])[A-Z]_[a-z]+', names(df), value=TRUE) 
types <- substr(types, 2, Inf) ## Remove the "A"
    for (tp in types) {
      aa <- df[[paste0('A', tp)]] ## "A" column
      cc <- df[[paste0('C', tp)]] ## "C" column
      df[[paste0('B', tp)]] <- ifelse(is.na(aa), aa, cc)
      }

答案 2 :(得分:0)

任务本身并不困难或复杂,但由于数据的排列方式,它似乎是这样。当您看到传达多个信息的变量名称时,自问是否可以更简单地排列数据通常会很有帮助。这个简单的主张是流行的&#34; tidy&#34;的核心。在R中进行数据处理的方法虽然我并不是那些以“&#34; tidy&#34;”的名义所做的一切的粉丝,但这个核心主张是合理的,你违反它(因为你&# 39;在这里做得非常出色)只是冒着使你的分析比你需要的更困难的风险。

好的第一步是重新排列数据,以便数据不会以列名编码:

new MyModelviewModel()

这可能看起来很多工作,但它使数据更容易使用,而且不仅仅适用于此特定操作。

现在数据已经转换为理智的安排,实际任务非常简单:

df <- read.table(
    text = "A1U_sweet  A2F_dip  A3U_bbq  C1U_sweet  C2F_dip  C3U_bbq
1          2        1        NA         NA       NA
NA         NA       NA       4          1        2
2          4        7        NA         NA       NA",
header = TRUE)

library(tidyr)

df <- data.frame(id = 1:nrow(df), df)
dfl <- gather(df, key = "key", value = "value", -id)
dfl <- separate(dfl, key, into = c("key", "kind", "type"), sep = c(1, 4))
df2 <- spread(dfl, key, value)
df2
##   id kind  type  A  C
## 1  1  1U_ sweet  1 NA
## 2  1  2F_   dip  2 NA
## 3  1  3U_   bbq  1 NA
## 4  2  1U_ sweet NA  4
## 5  2  2F_   dip NA  1
## 6  2  3U_   bbq NA  2
## 7  3  1U_ sweet  2 NA
## 8  3  2F_   dip  4 NA
## 9  3  3U_   bbq  7 NA

我强烈建议您将数据保留在这种安排中,因为当数据以这种方式表示时,其他操作可能会非常容易。如果你必须把它放回去(例如,为了显示目的),你可以这样做:

df2 <- transform(df2, B = ifelse(is.na(A), C, A))
df2
##   id kind  type  A  C B
## 1  1  1U_ sweet  1 NA 1
## 2  1  2F_   dip  2 NA 2
## 3  1  3U_   bbq  1 NA 1
## 4  2  1U_ sweet NA  4 4
## 5  2  2F_   dip NA  1 1
## 6  2  3U_   bbq NA  2 2
## 7  3  1U_ sweet  2 NA 2
## 8  3  2F_   dip  4 NA 4
## 9  3  3U_   bbq  7 NA 7

虽然这种方法显然比某些替代方案更冗长,但它具有解决困难根本原因的优点,而不是显示如何混淆并避免次优初始选择的后果。