使用R语言的for/if循环转换矩阵并提取列名求助
Got it, let's tackle this problem step by step. You don't need to mess with complicated for/if loops here—R has great vectorized tools to handle this cleanly, which is more efficient and readable than manual loops.
Step 1: Set up your sample data
First, let's recreate your matrix as a data frame (note: R automatically renames duplicate column names with a suffix like .1/.2 to avoid conflicts, but we can rename them explicitly for clarity):
# Create your sample data df <- data.frame( S = 1:5, K1 = c("A", "A", "A", "A", "A"), K1 = c("P", "A", "P", "P", "P"), K2 = c("A", "A", "A", "A", "A"), K2 = c("A", "A", "A", "A", "A"), K3 = c("A", "A", "A", "A", "A"), K3 = c("A", "A", "A", "A", "A"), K4 = c("P", "A", "P", "P", "A"), K4 = c("A", "P", "A", "A", "P"), K5 = c("A", "P", "A", "A", "A"), K5 = c("A", "P", "A", "A", "A") ) # Rename columns to be explicit (optional but helpful) colnames(df) <- c("S", "K1_1", "K1_2", "K2_1", "K2_2", "K3_1", "K3_2", "K4_1", "K4_2", "K5_1", "K5_2")
Step 2: Extract "P" column names for each sample
We'll use apply() to process each row, find columns where the value is "P", and pull their names. Then we'll reshape the result into your desired S V1 V2 format:
Option 1: Keep full column names (with suffixes)
# Extract columns with "P" for each row (exclude the first "S" column) p_columns <- apply(df[, -1], 1, function(row) { colnames(df[, -1])[row == "P"] }) # Convert the list result to a data frame and combine with the "S" column result <- cbind(df["S"], do.call(rbind, p_columns)) # Rename the output columns to match your desired format colnames(result) <- c("S", "V1", "V2")
Option 2: Use original group names (e.g., "K1" instead of "K1_2")
If you want to strip the suffixes and keep just the original K1/K2 etc. labels, modify the function to extract the prefix:
p_columns <- apply(df[, -1], 1, function(row) { # Get column names where value is "P" cols_with_p <- colnames(df[, -1])[row == "P"] # Remove suffixes (e.g., "_1" or "_2") to get original group names sub("_.*", "", cols_with_p) }) result <- cbind(df["S"], do.call(rbind, p_columns)) colnames(result) <- c("S", "V1", "V2")
Step 3: View the result
Running Option 2 will give you this output, which matches your expected format:
S V1 V2 1 1 K1 K4 2 2 K4 K5 3 3 K1 K4 4 4 K1 K4 5 5 K1 K4
Why this works instead of loops
apply()handles the row-wise iteration for you, so you don't have to write aforloop manually.- Vectorized operations (like
row == "P") are faster in R than looping through each element withifstatements, and they make the code shorter and easier to debug.
内容的提问来源于stack exchange,提问作者Mystra

