如何在函数中引用列名
How to refer to a column name in a function
我有一个df。如果 'info' 出现在一行中,我想要一个函数来获取列名并将其与单元格中的信息粘贴在一起,它们之间有一个“=”。我已经尝试了下面的函数,它可以工作,除了它没有引用右列中的列名
df <- data.frame('criteria1' = c('info','1', 'info', '', 'info'), "criteria2" = c('y','3', '', 'info', ''), "criteria3" = c('y','7', '', 'info', 'info'))
df[] <- sapply(df, function(x) ifelse(x == 'info', paste(colnames(df)[x], ' = ', x),''))
我的预期输出是这样的(删除列名并不重要,重要的只是来自单元格的信息)
df_exp <- data.frame('criteria1' = c('criteria1= info','', 'criteria1=info', '', 'criteria1 =info'), "criteria2" = c('','', '', 'criteria2 = info', ''), "criteria3" = c('','', '', 'criteria3 = info', 'criteria3 = info'))
我会选择列号,1:ncol(df)
(更快)或 seq(df)
。我用的是前者。
df <- sapply(1:ncol(df), function(x)
ifelse(df[[x]] == 'info', paste(colnames(df)[x], ' = ', df[[x]]),''))
df
# [,1] [,2] [,3]
# [1,] "criteria1 = info" "" ""
# [2,] "" "" ""
# [3,] "criteria1 = info" "" ""
# [4,] "" "criteria2 = info" "criteria3 = info"
# [5,] "criteria1 = info" "" "criteria3 = info"
另一种使用stack/unstack
的好方法:
r <- grep("info", tmp$values)
tmp <- stack(df)
tmp[r, 1] <- apply(tmp[r, 2:1], 1, paste, collapse="=")
tmp[-r, 1] <- "" ## in case you want non-"info" cells cleared
df <- unstack(tmp)
df
# criteria1 criteria2 criteria3
# 1 criteria1=info
# 2
# 3 criteria1=info
# 4 criteria2=info criteria3=info
# 5 criteria1=info criteria3=info
使用base
R(根据需要调整=
之前的间距):
use_names <- names(df)
data.frame(Map(function(x,y) ifelse(x=="info", paste0(y,"=",x),""), df, use_names))
criteria1 criteria2 criteria3
1 criteria1=info
2
3 criteria1=info
4 criteria2=info criteria3=info
5 criteria1=info criteria3=info
purrr
:
purrr::map2_df(df, names(df), function(x,y) ifelse(x=="info", paste0(y,"=",x),""))
# A tibble: 5 x 3
criteria1 criteria2 criteria3
<chr> <chr> <chr>
1 "criteria1=info" "" ""
2 "" "" ""
3 "criteria1=info" "" ""
4 "" "criteria2=info" "criteria3=info"
5 "criteria1=info" "" "criteria3=info"
数据:
df <- structure(list(criteria1 = c("info", "1", "info", "", "info"),
criteria2 = c("y", "3", "", "info", ""), criteria3 = c("y",
"7", "", "info", "info")), class = "data.frame", row.names = c(NA,
-5L))
我有一个df。如果 'info' 出现在一行中,我想要一个函数来获取列名并将其与单元格中的信息粘贴在一起,它们之间有一个“=”。我已经尝试了下面的函数,它可以工作,除了它没有引用右列中的列名
df <- data.frame('criteria1' = c('info','1', 'info', '', 'info'), "criteria2" = c('y','3', '', 'info', ''), "criteria3" = c('y','7', '', 'info', 'info')) df[] <- sapply(df, function(x) ifelse(x == 'info', paste(colnames(df)[x], ' = ', x),''))
我的预期输出是这样的(删除列名并不重要,重要的只是来自单元格的信息)
df_exp <- data.frame('criteria1' = c('criteria1= info','', 'criteria1=info', '', 'criteria1 =info'), "criteria2" = c('','', '', 'criteria2 = info', ''), "criteria3" = c('','', '', 'criteria3 = info', 'criteria3 = info'))
我会选择列号,1:ncol(df)
(更快)或 seq(df)
。我用的是前者。
df <- sapply(1:ncol(df), function(x)
ifelse(df[[x]] == 'info', paste(colnames(df)[x], ' = ', df[[x]]),''))
df
# [,1] [,2] [,3]
# [1,] "criteria1 = info" "" ""
# [2,] "" "" ""
# [3,] "criteria1 = info" "" ""
# [4,] "" "criteria2 = info" "criteria3 = info"
# [5,] "criteria1 = info" "" "criteria3 = info"
另一种使用stack/unstack
的好方法:
r <- grep("info", tmp$values)
tmp <- stack(df)
tmp[r, 1] <- apply(tmp[r, 2:1], 1, paste, collapse="=")
tmp[-r, 1] <- "" ## in case you want non-"info" cells cleared
df <- unstack(tmp)
df
# criteria1 criteria2 criteria3
# 1 criteria1=info
# 2
# 3 criteria1=info
# 4 criteria2=info criteria3=info
# 5 criteria1=info criteria3=info
使用base
R(根据需要调整=
之前的间距):
use_names <- names(df)
data.frame(Map(function(x,y) ifelse(x=="info", paste0(y,"=",x),""), df, use_names))
criteria1 criteria2 criteria3
1 criteria1=info
2
3 criteria1=info
4 criteria2=info criteria3=info
5 criteria1=info criteria3=info
purrr
:
purrr::map2_df(df, names(df), function(x,y) ifelse(x=="info", paste0(y,"=",x),""))
# A tibble: 5 x 3
criteria1 criteria2 criteria3
<chr> <chr> <chr>
1 "criteria1=info" "" ""
2 "" "" ""
3 "criteria1=info" "" ""
4 "" "criteria2=info" "criteria3=info"
5 "criteria1=info" "" "criteria3=info"
数据:
df <- structure(list(criteria1 = c("info", "1", "info", "", "info"),
criteria2 = c("y", "3", "", "info", ""), criteria3 = c("y",
"7", "", "info", "info")), class = "data.frame", row.names = c(NA,
-5L))