使用 R 循环列名
Loop on colum names with R
我正在使用一个数据框(称为 "dataEPM"),其中有几个列,其中一些确实有递增的列名(ke_1、ke_2、..、ke_8).
对于这些列,我想获得符合条件(==3)的行数,以及数据帧输出中的结果。所以我在列名上写了一个循环。
这里的代码:
output_nb <- matrix(ncol=2, nrow=8)
for (i in 1:8){
text <- paste("ke_",i, sep="")
nb_i <- nrow(dataEPM[dataEPM$text == "3",])
print(nrow(dataEPM[dataEPM$text == "3",]))
output_nb[i,1] <- i
output_nb[i,2] <- nb_i
}
output_nb <- data.frame(output_nb)
使用 print 命令,我可以看到 nrow(dataEPM[dataEPM$text == "3",])
始终等于 0,但当我替换列名(例如 nrow(dataEPM[dataEPM$ke_1 == "3",])
)时,事实并非如此。所以我假设这里不接受这种写列名的方式。
你能告诉我如何解决这个问题吗?提前致谢。
如果您对 tidyverse 解决方案持开放态度:
library(tidyverse)
#dataframe with many ke_# columns
dataEPM <- tibble(ke_1 = c(1, 2, 3, 4, 5), # 1 three
ke_2 = c(1, 2, 3, 3, 5), # 2 threes
ke_3 = c(1, 2, 3, 3, 3), # 3 threes
ke_4 = c(1, 3, 3, 3, 3)) # 4 threes
dataEPM %>%
pivot_longer(starts_with("ke"), "new_col") %>% #combine all ke_# columns into one col
dplyr::filter(value == 3) %>% #filter for values ==3
group_by(new_col) %>% #group by unique ke_#
summarize(num = n()) #count # occurences in each group
# A tibble: 4 x 2
new_col nrow
<chr> <int>
1 ke_1 1
2 ke_2 2
3 ke_3 3
4 ke_4 4
我们可以在 base R
中的逻辑 vector
上使用 colSums
stack(colSums(dataEPM == 3))[2:1]
# ind values
#1 ke_1 1
#2 ke_2 2
#3 ke_3 3
#4 ke_4 4
数据
dataEPM <- data.frame(ke_1 = c(1, 2, 3, 4, 5), # 1 three
ke_2 = c(1, 2, 3, 3, 5), # 2 threes
ke_3 = c(1, 2, 3, 3, 3), # 3 threes
ke_4 = c(1, 3, 3, 3, 3)) # 4 threes
以下应该有效:
for (i in 1:8){
text_ <- paste("ke_",i, sep="")
nb_i <- nrow(dataEPM[dataEPM[,text_] == "3",])
print(nrow(dataEPM[dataEPM[,text_] == "3",]))
}
只需使用简单的布尔过滤器。如果有效请告诉我!
我正在使用一个数据框(称为 "dataEPM"),其中有几个列,其中一些确实有递增的列名(ke_1、ke_2、..、ke_8). 对于这些列,我想获得符合条件(==3)的行数,以及数据帧输出中的结果。所以我在列名上写了一个循环。 这里的代码:
output_nb <- matrix(ncol=2, nrow=8)
for (i in 1:8){
text <- paste("ke_",i, sep="")
nb_i <- nrow(dataEPM[dataEPM$text == "3",])
print(nrow(dataEPM[dataEPM$text == "3",]))
output_nb[i,1] <- i
output_nb[i,2] <- nb_i
}
output_nb <- data.frame(output_nb)
使用 print 命令,我可以看到 nrow(dataEPM[dataEPM$text == "3",])
始终等于 0,但当我替换列名(例如 nrow(dataEPM[dataEPM$ke_1 == "3",])
)时,事实并非如此。所以我假设这里不接受这种写列名的方式。
你能告诉我如何解决这个问题吗?提前致谢。
如果您对 tidyverse 解决方案持开放态度:
library(tidyverse)
#dataframe with many ke_# columns
dataEPM <- tibble(ke_1 = c(1, 2, 3, 4, 5), # 1 three
ke_2 = c(1, 2, 3, 3, 5), # 2 threes
ke_3 = c(1, 2, 3, 3, 3), # 3 threes
ke_4 = c(1, 3, 3, 3, 3)) # 4 threes
dataEPM %>%
pivot_longer(starts_with("ke"), "new_col") %>% #combine all ke_# columns into one col
dplyr::filter(value == 3) %>% #filter for values ==3
group_by(new_col) %>% #group by unique ke_#
summarize(num = n()) #count # occurences in each group
# A tibble: 4 x 2
new_col nrow
<chr> <int>
1 ke_1 1
2 ke_2 2
3 ke_3 3
4 ke_4 4
我们可以在 base R
vector
上使用 colSums
stack(colSums(dataEPM == 3))[2:1]
# ind values
#1 ke_1 1
#2 ke_2 2
#3 ke_3 3
#4 ke_4 4
数据
dataEPM <- data.frame(ke_1 = c(1, 2, 3, 4, 5), # 1 three
ke_2 = c(1, 2, 3, 3, 5), # 2 threes
ke_3 = c(1, 2, 3, 3, 3), # 3 threes
ke_4 = c(1, 3, 3, 3, 3)) # 4 threes
以下应该有效:
for (i in 1:8){
text_ <- paste("ke_",i, sep="")
nb_i <- nrow(dataEPM[dataEPM[,text_] == "3",])
print(nrow(dataEPM[dataEPM[,text_] == "3",]))
}
只需使用简单的布尔过滤器。如果有效请告诉我!